1. 程式人生 > >Android 多程序基礎

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