Android 多程序基礎
為何要開啟多程序
為何開啟android應用要開啟多程序,主要有以下幾點:
1.單程序所分配的記憶體不夠,需要更多的記憶體。在早期android系統只為一個單程序的應用分配了16M的可用記憶體,隨著手機的硬體的提升和android系統的改進,雖然可分配記憶體越來越多,但仍舊可以通過開啟多程序來獲取更多的記憶體來處理自己App的業務,從最近裝置的24/32/48 MB以及舊裝置極小的16 MB便可以看出
2.獨立執行的元件,比如個推,它的服務會另開一個程序。
3.執行一些”不可見人”的操作,比如獲取使用者的隱私資料,比如雙守護程序來防止被使用者殺掉
如何開啟多程序
我們只需要在AndroidManifest.xml中的配置 android:process就可以了
package="com.example.processtest"
<service android:name="ProcessService"
android:process=":test"
></service>
這裡選擇“remote”這個名字是隨意主觀的,你也可以取其他的名字。冒號“:”則代替當前應用的包名,所以MyService跑在程序名為“com.example.processtest:remote”的程序中。我們也可以設定 android:process=”com.example.processtest.remote”,這樣MyService跑在程序名為“com.example.processtest.remote”的程序中。這兩種命名也是有區別的,如果被設定的程序名是以一個冒號開頭的,則這個新的程序對於這個應用來說是私有的,當它被需要或者這個服務需要在新程序中執行的時候,這個新程序將會被建立。如果這個程序的名字是以小寫字元開頭的,則這個服務將執行在一個以這個名字命名的全域性的程序中,當然前提是它有相應的許可權。這將允許在不同應用中的各種元件可以共享一個程序,從而減少資源的佔用。
開啟多程序引出的問題
開啟多程序會使Application執行兩次
現在很多開發者都習慣在Application中做初始化操作以及資料的傳遞操作,這顯然是不妥當的,解決的方法就是得到每個程序的名稱,如果程序的名稱和我們應用的程序名稱相同則做我們應用的操作,如果不是則做其他程序的操作
獲取程序pid和程序名稱
/**
* 當前的程序名
* @param context
* @return
*/
public static String getCurProcessName(Context context) {
int pid = android.os.Process.myPid();//當前程序pid
ActivityManager mActivityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager
.getRunningAppProcesses()) {
if (appProcess.pid == pid) {
return appProcess.processName;
}
}
return null;
}
根據不同的程序做不同的初始化操作
public class MyApplication extends Application {
public static String name;
@Override
public void onCreate() {
// TODO 自動生成的方法存根
super.onCreate();
int id = android.os.Process.myPid();
if ("com.example.processtest".equals(Tools
.getCurProcessName(getApplicationContext()))) {
Log.d("xx",
id + ";" + Tools.getCurProcessName(getApplicationContext()));
//打印出來的是主程序pid 和 主程序的名稱
name = "主程序";
} else {
name = "輔助程序";
Log.d("xx",
id + ";" + Tools.getCurProcessName(getApplicationContext()));
//打印出來的是另一個程序pid 和 另一個程序的名稱
}
}
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("xxM", android.os.Process.myPid()+"");
Intent intent=new Intent(getApplicationContext(), ProcessService.class);
startService(intent);
Log.d("xxM", MyApplication.name); //列印的是主程序
}
}
public class ProcessService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO 自動生成的方法存根
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO 自動生成的方法存根
Log.d("xxx",
android.os.Process.myPid() + ";"
+ Tools.getCurProcessName(getApplicationContext()));
Log.d("xxS", MyApplication.name);//列印的是輔助程序
return super.onStartCommand(intent, flags, startId);
}
}