Android开发Android开发经验谈Android技术知识

如何开启多进程?应用是否可以开启N个进程?

2020-04-23  本文已影响0人  InFatuated

开启多进程
首先我们写一个Activity并启动一个service

package com.example.infatuated;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent MyServiceIntent = new Intent(this, MyService.class);
        this.startService(MyServiceIntent);
    }
}

service的代码:

package com.example.infatuated;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;



public class MyService extends Service {

    private static final String TAG = "qmsggg";

    @Override
    public void onCreate() {
        Log.i(TAG, "MyService is oncreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "MyProcessActivity is created: ");
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "ODestroy");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

最后我们只需要在AndroidManifest.xml中的配置 android:process就可以了

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service android:name=".MyService" android:label="@string/app_name" android:process=":test"/>
</application>

需要特别说明的是,android:process=":test" 中的test名字是自定义的,而冒号":"的含义是当前进程名前附加上当前的包名。那么刚刚所创建出的Service的完整进程名就为com.example.infatuated:test.
当然你也可以自己设置完整地进程名,如android:process="com.example.double:test"这便是一种完整地命名方式。
而更重要的是两种命名方式的区别在于:

接下来我们测试验证一下:

public class MyApplication extends Application {
    private static final String TAG = "MyApplication";
    @Override
    public void onCreate() {
        super.onCreate();
        int pid = android.os.Process.myPid(); 
        Log.i(TAG, "MyApplication is oncreate===="+"pid="+pid);
    }
 } 

日志结果如下:

多进程log1.png

可以看到MyApplication的OnCreate方法执行了两次。
分别是在com.example.infatuated和com.example.infatuated:test 两个进程之中各执行了一次。
所以这就衍生出了一个问题,很多开发者都习惯在Application的子类里面去做相应的初始化和数据化存储操作,如果我们开启多个进程让Application的子类各个回调方法都执行多次,这显然是有问题的。
所以,我们应该区分进程,如果是应用进程,则做应用的相关操作,如果是其他进程(在这里是一个服务),就做其他的操作

package com.example.infatuated;

import android.app.ActivityManager;
import android.app.Application;
import android.util.Log;

public class MyApplication extends Application {
  private static final String TAG = "MyApplication";
    @Override
    public void onCreate() {
        super.onCreate();
        int pid = android.os.Process.myPid();
        Log.i(TAG, "MyApplication is onCreate===="+"pid="+pid);

        String processnameString = "";
        ActivityManager manager =(ActivityManager)this.getSystemService(getApplicationContext().ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo appProcessInfo : manager.getRunningAppProcesses()) {
            if (appProcessInfo.pid == pid) {
                processnameString = appProcessInfo.processName;
                Log.i(TAG, "processName=" + processnameString);
            }
        }
        if ("com.example.infatuated:test".equals(processnameString)) {
            Log.i(TAG, "processName = " + processnameString);
        }
    }
多进程log2.png

总结:

上一篇下一篇

猜你喜欢

热点阅读