小議Android多進程以至Application屢次初始化

最近遇到一個bug,當應用加了多進程後,好比總共進程數爲N,會出如今`startService()`時`onStartCommand()`方法會被重複調用`(N-1)`次的奇怪現象。android

 

***
## 禍起
>最近遇到兩個模塊互不相干卻受到影響的奇怪問題,一個push模塊和一個DaemonProcess模塊在一塊兒後,會出現以下現像的問題
***
當DaemonProcess爲應用加了多進程後,好比總共進程數爲N,會出現push模塊在`startService()`時`onStartCommand()`方法會被重複調用`(N-1)`次的奇怪現象。
***app


## 尋蹤ide

* 由於咱們用的是Jpush的緣由,一開始覺得是Jpush,但最後發現是由於引用多進程的緣由
* 再尋找下去發現 調用一次`startService()`時`onStartCommand()`運行屢次
* 而這二者有何關係呢測試


## 舉證this

> Demo測試:
> 首先在Application中申明四個service,其中`ServiceA`和`ServiceC`都各自另開一個進程,`ServiceB`和`ServiceD`都在主進程中,AndroidManifest.xml以下:xml

```進程

<service android:name=".ServiceA"
android:process="com.hujiang.test.servicea"
android:exported="true"/>

<service android:name=".ServiceB"
android:exported="false"/>

<service android:name=".ServiceC"
android:process="com.hujiang.test.servicec"
android:exported="true"/>get

<service android:name=".ServiceD"
android:exported="false"/>

```虛擬機

此時在Application中啓動四個Service
```it

startService(new Intent(this, ServiceA.class));
startService(new Intent(this, ServiceB.class));
startService(new Intent(this, ServiceC.class));
startService(new Intent(this, ServiceD.class));

```
同時各Service打下以下log:

```
public static final String TAG = ServiceB.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"onCreate" + "pid:" + android.os.Process.myPid());
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG,"onStartCommand" + "pid:" + android.os.Process.myPid());
return super.onStartCommand(intent, flags, startId);
}

```

在log中會發現
`onCreate()`方法各執行一遍,這個是正常的,但`onStartCommand()`方法目前執行了三遍,由於共3個進程。

 

## 真相

1. N個進程,N個獨立的虛擬機,Application被N次初使化
2. 處理時應該在Application中分進程初始化數據


<!--more-->
## 劍譜


以下解決方案

mProcessName = getCurrentProcessName(this);
Log.i(TAG, "onCreate" + "getProcessName:" + mProcessName);
Log.i(TAG, "init_all_process");
if(TextUtils.equals(mProcessName, getPackageName())){
Log.i(TAG, "init_main_process");
} else if(TextUtils.equals(getProcessName(this, android.os.Process.myPid()), "com.hujiang.test.servicea")){
Log.i(TAG, "init_a_process");
}else if(TextUtils.equals(getProcessName(this, android.os.Process.myPid()), "com.hujiang.test.servicec")){
Log.i(TAG, "init_c_process");
}

獲取當前進程名稱:


private String getCurrentProcessName(Context context) {
int pid = android.os.Process.myPid();
ActivityManager mActivityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager
.getRunningAppProcesses()) {
if (appProcess.pid == pid) {
return appProcess.processName;
}
}
return null;
}

分別在本身的進程中初始化

相關文章
相關標籤/搜索