99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

關(guān)于 Android 應(yīng)用多進(jìn)程的整理

發(fā)布時(shí)間:2017-01-16 23:06  回復(fù):0  查看:2239   最后回復(fù):2017-01-16 23:06  

在計(jì)算機(jī)操作系統(tǒng)中,進(jìn)程是進(jìn)行資源分配和調(diào)度的基本單位。這對于基于Linux內(nèi)核的Android系統(tǒng)也不例外。在Android的設(shè)計(jì)中,一個(gè)應(yīng)用默認(rèn)有一個(gè)()進(jìn)程。但是我們通過配置可以實(shí)現(xiàn)一個(gè)應(yīng)用對應(yīng)多個(gè)進(jìn)程。

  本文將試圖對于Android開發(fā)中應(yīng)用多進(jìn)程做一些整理總結(jié)。

  android:process

  · 應(yīng)用實(shí)現(xiàn)多進(jìn)程需要依賴于android:process這個(gè)屬性

  · 適用元素:Application, Activity, BroadcastReceiver, Service, ContentProvider

  · 通常情況下,這個(gè)屬性的值應(yīng)該是”:“開頭。表示這個(gè)進(jìn)程是應(yīng)用私有的。無法在在跨應(yīng)用之間共用。

  · 如果該屬性值以小寫字母開頭,表示這個(gè)進(jìn)程為全局進(jìn)程??梢员欢鄠€(gè)應(yīng)用共用。(文章結(jié)尾會(huì)探討這個(gè)問題)

  一個(gè)應(yīng)用 android:process 簡單示例

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

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

 

  應(yīng)用多進(jìn)程有什么好處

  增加App可用內(nèi)存

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

  這些有限的內(nèi)存對于普通的App還算是夠用,但是對于展示大量圖片的應(yīng)用來說,顯得實(shí)在是捉襟見肘。

  仔細(xì)研究一下,你會(huì)發(fā)現(xiàn)原來系統(tǒng)的這個(gè)限制是作用于進(jìn)程的(畢竟進(jìn)程是作為資源分配的基本單位)。意思就是說,如果一個(gè)應(yīng)用實(shí)現(xiàn)多個(gè)進(jìn)程,那么這個(gè)應(yīng)用可以獲得更多的內(nèi)存。

  于是,增加App可用內(nèi)存成了應(yīng)用多進(jìn)程的重要原因。

  獨(dú)立于主進(jìn)程

  除了增加App可用內(nèi)存之外,確保使用多進(jìn)程,可以獨(dú)立于主進(jìn)程,確保某些任務(wù)的執(zhí)行和完成。

  舉一個(gè)簡單的例子,之前的一個(gè)項(xiàng)目存在退出的功能,其具體實(shí)現(xiàn)為殺掉進(jìn)程。為了保證某些統(tǒng)計(jì)數(shù)據(jù)上報(bào)正常,不受當(dāng)前進(jìn)程退出的影響,我們可以使用獨(dú)立的進(jìn)程來完成。

  多進(jìn)程的不足與缺點(diǎn)

  數(shù)據(jù)共享問題

  · 由于處于不同的進(jìn)程導(dǎo)致了數(shù)據(jù)無法共享內(nèi)容,無論是static變量還是單例模式的實(shí)現(xiàn)。

  · SharedPreferences 還沒有增加對多進(jìn)程的支持。

  · 跨進(jìn)程共享數(shù)據(jù)可以通過Intent,Messenger,AIDL等。

  SQLite容易被鎖

  · 由于每個(gè)進(jìn)程可能會(huì)使用各自的SQLOpenHelper實(shí)例,如果兩個(gè)進(jìn)程同時(shí)對數(shù)據(jù)庫操作,則會(huì)發(fā)生SQLiteDatabaseLockedException等異常。

  · 解決方法:可以使用ContentProvider來實(shí)現(xiàn)或者使用其他存儲(chǔ)方式。

  不必要的初始化

  · 多進(jìn)程之后,每個(gè)進(jìn)程在創(chuàng)建的時(shí)候,都會(huì)執(zhí)行自己的Application.onCreate方法。

  · 通常情況下,onCreate中包含了我們很多業(yè)務(wù)相關(guān)的初始化,更重要的這其中沒有做按照進(jìn)程按需初始化,即每個(gè)進(jìn)程都會(huì)執(zhí)行全部的初始化。

  · 按需初始化需要根據(jù)當(dāng)前進(jìn)程名稱,進(jìn)行最小需要的業(yè)務(wù)初始化。

  · 按需初始化可以選擇簡單的if else判斷,也可以結(jié)合工廠模式

  一些簡單的代碼示例

  獲取當(dāng)前的進(jìn)程名

  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;

  }

  基本的進(jìn)程初始化類

  這個(gè)類用來每個(gè)進(jìn)程共用的業(yè)務(wù)初始化邏輯。

  public class AppInitialization {

  @CallSuper

  public void onAppCreate(Application application) {

  Log.i("AppInitialization", "onAppCreate is being executed.");

  }

  }

  工廠模式的應(yīng)用

  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.");

  }

  }

  }

  具體的調(diào)用時(shí)的代碼

  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);

  }

  }

  }

  是否需要多進(jìn)程

  判斷是否需要多進(jìn)程,需要視具體情況而定。

  內(nèi)存限制

  · 研究內(nèi)存占用居高不下的原因

  · 如果是由內(nèi)存泄漏導(dǎo)致,嘗試解決來降低內(nèi)存占用

  · 如有必要,可以通過配置largeHeap嘗試解決

  除了內(nèi)存限制之外,還需要考慮是否真的需要獨(dú)立于主進(jìn)程來執(zhí)行某些操作。

  關(guān)于android:process的其他問題

  在android:process部分我們提到,如果這個(gè)屬性值以小寫字母開頭,那么就是全局的進(jìn)程,可以被其他應(yīng)用共用。

  所謂的共用,指的是不同的App的組件運(yùn)行在同一個(gè)指定的進(jìn)程中。

  準(zhǔn)備條件

  受制于Android系統(tǒng)的安全機(jī)制,我們需要做到以下兩個(gè)準(zhǔn)備條件才可以。

  · 這個(gè)應(yīng)用使用同樣的簽名

  · 兩個(gè)應(yīng)用指定同一個(gè)android:sharedUserId的值

  具體示例

  第一個(gè)AppManifest文件,AnotherActivity運(yùn)行在名為droidyue.com的進(jìn)程中。

  <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>

  第二個(gè)AppManifest文件,SecondActivity運(yùn)行在名為droidyue.com的進(jìn)程中。

  <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>

  上面的AnotherActivitySecondActivity會(huì)運(yùn)行在一個(gè)名為droidyue.com的進(jìn)程中,盡管他們位于不同的App中。

但是這種共用進(jìn)程的方式會(huì)引發(fā)很多問題,不太建議大家使用。

 

來源:技術(shù)小黑屋

 

您還未登錄,請先登錄

熱門帖子

最新帖子

?