国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

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

2019-12-12 03:53:07
字體:
來源:轉載
供稿:網友

前言

在計算機操作系統中,進程是進行資源分配和調度的基本單位。這對于基于Linux內核的Android系統也不例外。在Android的設計中,一個應用默認有一個(主)進程。但是我們通過配置可以實現一個應用對應多個進程。

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

android:process

  • 應用實現多進程需要依賴于android:process這個屬性
  • 適用元素:Application, Activity, BroadcastReceiver, Service, ContentProvider。
  • 通常情況下,這個屬性的值應該是”:“開頭。表示這個進程是應用私有的。無法在在跨應用之間共用。
  • 如果該屬性值以小寫字母開頭,表示這個進程為全局進程。可以被多個應用共用。(文章結尾會探討這個問題)

一個應用 android:process 簡單示例

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

應用多進程有什么好處

增加App可用內存

在Android中,默認情況下系統會為每個App分配一定大小的內存。比如從最早的16M到后面的32M或者48M等。具體的內存大小取決于硬件和系統版本。

這些有限的內存對于普通的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系統的安全機制,我們需要做到以下兩個準備條件才可以。

  1. 這個應用使用同樣的簽名
  2. 兩個應用指定同一個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中多進程的一些淺顯的研究,如有問題,歡迎指正。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 抚宁县| 盐源县| 防城港市| 河曲县| 榆树市| 买车| 苏尼特右旗| 皮山县| 晋州市| 佛冈县| 黑龙江省| 盐城市| 营山县| 华坪县| 冕宁县| 新民市| 弥勒县| 朔州市| 鹤岗市| 龙里县| 开原市| 同仁县| 淳安县| 盐源县| 肇庆市| 五台县| 屯留县| 夏河县| 封开县| 四川省| 汽车| 共和县| 沅陵县| 武冈市| 英德市| 柳林县| 平武县| 关岭| 桑日县| 腾冲县| 积石山|