Android中應用多進程的整理總結

前言android

在計算機操做系統中,進程是進行資源分配和調度的基本單位。這對於基於Linux內核的Android系統也不例外。在Android的設計中,一個應用默認有一個(主)進程。可是咱們經過配置能夠實現一個應用對應多個進程。數據庫

本文將試圖對於Android中應用多進程作一些整理總結。編程

android:process安全

    應用實現多進程須要依賴於android:process這個屬性
    適用元素:Application, Activity, BroadcastReceiver, Service, ContentProvider。
    一般狀況下,這個屬性的值應該是」:「開頭。表示這個進程是應用私有的。沒法在在跨應用之間共用。
    若是該屬性值以小寫字母開頭,表示這個進程爲全局進程。能夠被多個應用共用。(文章結尾會探討這個問題)app

一個應用 android:process 簡單示例ide

    
<activity android:name=".MusicPlayerActivity" android:process=":music"/>
 
<activity android:name=".AnotherActivity" android:process="droidyue.com"/>性能

應用多進程有什麼好處學習

增長App可用內存動畫

在Android中,默認狀況下系統會爲每一個App分配必定大小的內存。好比從最先的16M到後面的32M或者48M等。具體的內存大小取決於硬件和系統版本。this

這些有限的內存對於普通的App還算是夠用,可是對於展現大量圖片的應用來講,顯得實在是捉襟見肘。

仔細研究一下,你會發現原來系統的這個限制是做用於進程的(畢竟進程是做爲資源分配的基本單位)。意思就是說,若是一個應用實現多個進程,那麼這個應用能夠得到更多的內存。

因而,增長App可用內存成了應用多進程的重要緣由。

獨立於主進程

除了增長App可用內存以外,確保使用多進程,能夠獨立於主進程,確保某些任務的執行和完成。

舉一個簡單的例子,以前的一個項目存在退出的功能,其具體實現爲殺掉進程。爲了保證某些統計數據上報正常,不受當前進程退出的影響,咱們可使用獨立的進程來完成。

多進程的不足與缺點

數據共享問題

    因爲處於不一樣的進程致使了數據沒法共享內容,不管是static變量仍是單例模式的實現。
    SharedPreferences 尚未增長對多進程的支持。
    跨進程共享數據能夠經過Intent,Messenger,AIDL等。

SQLite容易被鎖

    因爲每一個進程可能會使用各自的SQLOpenHelper實例,若是兩個進程同時對數據庫操做,則會發生SQLiteDatabaseLockedException等異常。
    解決方法:可使用ContentProvider來實現或者使用其餘存儲方式。

沒必要要的初始化

    多進程以後,每一個進程在建立的時候,都會執行本身的Application.onCreate方法。
    一般狀況下,onCreate中包含了咱們不少業務相關的初始化,更重要的這其中沒有作按照進程按需初始化,即每一個進程都會執行所有的初始化。
    按需初始化須要根據當前進程名稱,進行最小須要的業務初始化。
    按需初始化能夠選擇簡單的if else判斷,也能夠結合工廠模式

一些簡單的代碼示例

獲取當前的進程名

private String getCurrentProcessName() {
 String currentProcName = "";
 int pid = android.os.Process.myPid();
 ActivityManager manager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
 for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
  if (processInfo.pid == pid) {
   currentProcName = processInfo.processName;
   break;
  }
 }
 return currentProcName;
}

基本的進程初始化類

這個類用來每一個進程共用的業務初始化邏輯。

    
public class AppInitialization {
 @CallSuper
 public void onAppCreate(Application application) {
  Log.i("AppInitialization", "onAppCreate is being executed.");
 }
}

工廠模式的應用

    
public class AppInitFactory {
 public static AppInitialization getAppInitialization(String processName) {
  AppInitialization appInitialization;
  if (processName.endsWith(":game")) {
   appInitialization = new GameAppInitialization();
  } else if (processName.endsWith(":music")) {
   appInitialization = new MusicAppInitialization();
  } else {
   appInitialization = new AppInitialization();
  }
  return appInitialization;
 }
 
 static class GameAppInitialization extends AppInitialization {
  @Override
  public void onAppCreate(Application application) {
   super.onAppCreate(application);
   Log.i("GameAppInitialization", "onAppCreate is being executed.");
  }
 }
 
 static class MusicAppInitialization extends AppInitialization {
  @Override
  public void onAppCreate(Application application) {
   super.onAppCreate(application);
   Log.i("MusicAppInitialization", "onAppCreate is being executed.");
  }
 }
}

具體的調用時的代碼

    
public class MyApplication extends Application{
 private static final String LOGTAG = "MyApplication";
 
 @Override
 public void onCreate() {
  super.onCreate();
  String currentProcessName = getCurrentProcessName();
  Log.i(LOGTAG, "onCreate currentProcessName=" + currentProcessName);
  AppInitialization appInitialization = AppInitFactory.getAppInitialization(currentProcessName);
  if (appInitialization != null) {
   appInitialization.onAppCreate(this);
  }
 }
}

是否須要多進程

判斷是否須要多進程,須要視具體狀況而定。

內存限制

    研究內存佔用居高不下的緣由
    若是是由內存泄漏致使,嘗試解決來下降內存佔用
    若有必要,能夠經過配置largeHeap嘗試解決

除了內存限制以外,還須要考慮是否真的須要獨立於主進程來執行某些操做。

關於android:process的其餘問題

在android:process部分咱們提到,若是這個屬性值以小寫字母開頭,那麼就是全局的進程,能夠被其餘應用共用。

所謂的共用,指的是不一樣的App的組件運行在同一個指定的進程中。

準備條件

受制於Android系統的安全機制,咱們須要作到如下兩個準備條件才能夠。

    這個應用使用一樣的簽名
    兩個應用指定同一個android:sharedUserId的值

具體示例

第一個App的Manifest文件,AnotherActivity運行在名爲droidyue.com的進程中。

    
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.droidyue.androidmutipleprocesssample"
  android:sharedUserId="droidyue.com"
 >
 
 <application
   android:name=".MyApplication"
   android:allowBackup="true"
   android:icon="@mipmap/ic_launcher"
   android:label="@string/app_name"
   android:supportsRtl="true"
   android:theme="@style/AppTheme">
 
  <activity android:name=".AnotherActivity" android:process="droidyue.com"/>
 </application>
 
</manifest>

第二個App的Manifest文件,SecondActivity運行在名爲droidyue.com的進程中。

    
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.jishuxiaoheiwu.accessfromanotherprocess"
 android:sharedUserId="droidyue.com"
 >
 
 <application
  android:allowBackup="true"
  android:icon="@mipmap/ic_launcher"
  android:label="@string/app_name"
  android:supportsRtl="true"
  android:theme="@style/AppTheme">
  <activity android:name=".SecondActivity"
   android:process="droidyue.com"
   />
 </application>
 
</manifest>

上面的AnotherActivity和SecondActivity會運行在一個名爲droidyue.com的進程中,儘管他們位於不一樣的App中。

可是這種共用進程的方式會引起不少問題,不太建議你們使用。

以上就是我關於Android中多進程的一些淺顯的研究,若有問題,歡迎指正。

總結

以上就是這篇文章的所有內容了,但願本文的內容對你們的學習或者工做能帶來必定的幫助,若是有疑問你們能夠留言交流。
您可能感興趣的文章:

    Android應用開發SharedPreferences存儲數據的使用方法     Android 動畫之TranslateAnimation應用詳解     Android 動畫之ScaleAnimation應用詳解     Android開發中多進程共享數據簡析     Android 多進程資料總結     Android 進程間通訊實現原理分析     Android應用程序四大組件之使用AIDL如何實現跨進程調用Service     Android編程防止進程被第三方軟件殺死的方法     解析後臺進程對Android性能影響的詳解     Android結束進程的方法詳解

相關文章
相關標籤/搜索