Android開啟多進程

來源:互聯網
上載者:User

標籤:

1. 為何要開啟多進程
為何開啟android應用要開啟多進程,主要有以下幾點:

  • 單進程所分配的記憶體不夠,需要更多的記憶體。在早期android系統只為一個單進程的應用程式指派了16M的可用記憶體,隨著手機的硬體的提升和android系統的改進,雖然可分配記憶體越來越多,但仍舊可以通過開啟多進程來擷取更多的記憶體來處理自己App的業務

  • 獨立啟動並執行組件,比如個推,它的服務會另開一個進程。

  • 進行一些“不可告人”的操作的處理,比如雙守護進程,來儘力使自己的應用不被系統殺死,或者擷取使用者的個人資訊等其他資訊。

2. 開啟多進程
首先我們寫一個Activity並啟動一個service

public class MyProcessActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_my_process);        Intent myServiceIntent=new Intent(MyProcessActivity.this,MyService.class);        this.startService(myServiceIntent);    }}

service的代碼:

public class MyService extends Service {    private static final String TAG = "wangshu";    @Override    public void onCreate() {        Log.i(TAG,"MyService is oncreate");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.i(TAG, "MyProcessActivity is created: ");        return START_STICKY;    }    @Override    public void onDestroy() {        Log.i(TAG,"OnDestory");    }    @Override    public IBinder onBind(Intent arg0) {        return null;    }}

最後我們只需要在AndroidManifest.xml中的配置 android:process就可以了

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.liuwangshu.myprogress" >    <application        android:allowBackup="true"        android:name=".MyApplication"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme" >        <activity android:name=".MyProcessActivity" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <service            android:name=".MyService"            android:label="@string/app_name"            android:process=":remote">        </service>    </application></manifest>

這裡選擇”remote”這個名字是隨意主觀的,你也可以取其他的名字。冒號“:”的含義是在當前進程名前面附上當前的包名。那麼MyService的完整進程名為“com.example.liuwangshu.myprogress:remote”。我們也可以設定 android:process=”com.example.liuwangshu.myprogress.remote”,這是一種完整的命名方式。這兩種命名也是有區別的,如果被設定的進程名是以“:”開頭的,則這個新的進程對於這個應用來說是私人的,當它被需要或者這個服務需要在新進程中啟動並執行時候,這個新進程將會被建立。如果這個進程的名字是以小寫字元開頭的,則這個服務將運行在一個以這個名字命名的全域的進程中,當然前提是它有相應的許可權。這將允許在不同應用中的各種組件可以共用一個進程,從而減少資源的佔用。

現在我們運行程式我們可以看到我們應用開啟了兩個進程

3. 開啟多進程引出的問題
開啟多進程確實很簡單,但是同時也會帶來一些問題,其中一個就是繼承Application的類會執行多遍,我沒在Application的子類裡的oncreat方法中打log,來看看oncreat執行幾遍

public class MyApplication extends Application {    private static final String TAG = "wangshu";    @Override    public void onCreate() {        super.onCreate();        int pid = android.os.Process.myPid();         Log.i(TAG, "MyApplication is oncreate===="+"pid="+pid);    } }       

log中顯示MyApplication 的onCreate執行了兩次

但是現在很多的開發人員都習慣在Application 的子類裡去做應用的初始化和資料存放區的操作,如果我們開啟多個進程而讓Application 的子類的各個回調方法都執行多次這顯然是不多的,所以我們就應該區分進程,如果是應用的進程則做應用的操作,其他的進程(在這裡是一個服務)就做其他的操作。首先我們是知道應用的進程的名字的,我們通過for迴圈來得到各個進程的名字,如果得到的進程的名字和我們應用進程名相同,我們就應該做應用的操作

public class MyApplication extends Application {    private static final String TAG = "wangshu";    @Override    public void onCreate() {        super.onCreate();        int pid = android.os.Process.myPid();        Log.i(TAG, "MyApplication is oncreate====" + "pid=" + pid);        String processNameString = "";        ActivityManager mActivityManager = (ActivityManager) this.getSystemService(getApplicationContext().ACTIVITY_SERVICE);        for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses()) {            if (appProcess.pid == pid) {                processNameString = appProcess.processName;                Log.i(TAG, "processName=" + processNameString);            }        }        if ("com.example.liuwangshu.myprogress".equals(processNameString)) {            Log.i(TAG, "processName=" + processNameString + "-----work");        } else {            Log.i(TAG, "processName=" + processNameString + "-----work");        }    }}

來看看Log

總結一下開啟多進程所帶來的影響:

  • Application 會執行多次
  • 多線程完全失效
  • 靜態成員和單例模式失效
  • SharedPreferences變得不可靠

第一條我們已經說過了,第二條也無需解釋,第三條因為我們開啟了多個進程,它們是運行在自己虛擬機器上並分配了不同的地址空間,修改靜態成員只會在自己的進程中有效,同樣單例模式也是只有自己的進程中是單例,多個進程中就不能稱之為單例了,因為很可能多個進程都會存在這個所謂的單例。第四條SharedPreferences並不支援並發的讀取,多個進程可能存在並發的情況,這樣SharedPreferences的讀和寫都變得不可靠。

Android開啟多進程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.