Android進程詳解,android詳解
Android進程詳解
當一個應用啟動的時候,如果這個應用沒有其它組件已經在運行了,那麼系統就會為這個應用啟動一個新的Linux進程,這個進程只有一個線程,即我們熟知的main線程。預設情況下,一個應用的所有組件都運行在一個進程和線程(main)中。這點從Logcat的列印資訊可以看出,Logcat視圖中的Application那一欄,列印的是當前應用的進程的name值,而通常情況下是列印出的是manifes的package的值,這是因為我們的Application的標籤沒有設定progress的值,如果沒有設定的話,系統預設使用package的值來作為當前應用的進程的名字。當然,你完全可以安排不同的組件運行於不同的進程中,並且你可以為任何程式建立另外的線程,這點我們在做非同步作業更新介面的時候,如果使用Handler的方式的話,往往會新建立一個線程。如:
new Thread()
{
public void run()
{
…………………………………………..
mHandler.sendEmptyMessage(0);
}
}.start();
下面說一下,如何?同一個應用的不同組件運行在不同的進程中:
預設下,同一個應用的所有組件都運行在同一個進程中並且大多數程式不必改變這種情況,如果你非要同一個應用的不同組件運行在不同的進程中,也可以通過manifest檔案實現。
Manifest檔案中的所有支援android:process屬性的那些項(<activity>,<service>,<receiver>,和<provider>)都可以指定一個進程,設定該屬性之後的組件將在該屬性所對應的進程中運行。你可以設定這個屬性使每個組件運行於其自己的進程或只是其中一些組件共用一個進程,你也可以設定android:process以使不同應用的組件可以運行於同一個進程。<application>元素也支援android:process屬性,用於為所有的組件指定一個預設值。Android可能在某些時刻決定關閉一個進程,比如在記憶體不足的時候,系統會自動關閉一些其他應用的後台進程,以保持當前正在啟動並執行進程的運行。
進程的生命週期:Android系統會盡量維持一個進程的生命,直到最終需要為新的更重要的進程騰出記憶體空間。為了決定哪個該殺哪個該留,系統會根據運行於進程內的組件和組件的狀態把進程置於不同的重要性等級。當需要系統資源時,重要性等級越低的先被淘汰。Android重要性等級被分為5個等級(從高到低):(1)前台進程(2)可見進程(3)服務進程(4)後台進程(5)空進程.
進程的優先順序:
當系統的記憶體不足時,android系統將根據進程優先順序選擇殺死一些不太重要的進程。進程優先順序從高到低分別為:
1、 前台進程,以下進程為前台進程:
(1)進程中包含處於前台的正與使用者互動的activity;
(2)進程中包含與前台activity綁定的service
(3)進程中包含了調用了startForeground()方法的service
(4)進程中包含正在執行onCreate(),onStart(),或onDestroy()方法的service
(5)進程中包含正在執行onReceive()方法的BroadcastReceiver
系統中前台進程的數量很少,前台進程幾乎不會被殺死,只有當記憶體低到無法保證所有的前台進程同時運行時才會選擇殺死某個前台進程。
2、 可見進程,以下進程為可見進程:
(1)進程中包含未處於前台但仍然可見的activity(調用了activity的onPause()方法),典型的情況是運行activity時彈出對話方塊,此時的activity雖然不是前台activity,但是其仍然可見。
(2)進程中包含於可見activity綁定的service
可視進程不會被系統殺死,除非為了保證前台進程的運行而不得已為之。
3、 服務進程:進程中包含已啟動的service
4、 後台進程:進程中包含不可見的activity(onStop()方法調用後的activity)。後台進程不會直接影響使用者體驗,為了保證前台進程/可視進程/服務進程的運行,系統隨時都有可能殺死一個後台進程。一個正確的實現了生命週期方法的activity處於後台時被系統殺死,可以在使用者重新啟動它時恢複之前的運行狀態。
5、 空進程:不包含任何處於活動狀態的進程是一個空進程,系統經常殺死空進程,這不會造成任何影響。空進程存在的唯一理由是為了緩衝一些啟動資料。
講到這裡理論部分已經講完了,現在咱們通過一個Demo來加深一下理解。
首先看一下測試Demo的Manifest檔案,代碼如下:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.gc.testprogressdemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /><!-- android:process="newpackage.test" 設定此Demo的進程名字為newpackage.test,即此Demo所有組件預設都運行在該進程中 --> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:process="newpackage.test" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- android:process="NewProgress." 將NewProgress組件運行在NewProgress.進程裡。 注意:android:process的值的格式須為:xxx.xxxx。這個必須含有一個“.”,否則編譯通不過。 測試編譯環境為5.0 --> <activity android:name=".NewProgress" android:label="@string/app_name" android:process="NewProgress." /> <activity android:name=".NowProgress" android:label="@string/app_name" /> </application></manifest>
大家都過上面代碼可以看到,此Demo是運行在進程newpackage.test裡的,NewProgress這個Activity是運行在NewProgress.這個進程裡的,下面大家先看一下運行,如所示:
下面給出擷取當前進程的名字的代碼,如下:
package com.gc.testprogressdemo.uitls;import android.app.ActivityManager;import android.content.Context;/** * 返回當前進程的名字 * @author Android將軍 * */public class GetProgressName {public static String getCurrentProgressName(Context context){int pid=android.os.Process.myPid();ActivityManager mActivityManager=(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);for(ActivityManager.RunningAppProcessInfo appProcess:mActivityManager.getRunningAppProcesses()){if(appProcess.pid==pid){return appProcess.processName;}}return null;}}
由於此Demo比較簡單,故不在過多的闡述,文章末尾會附上Demo的。
至於如何判斷當前進程是哪一個層級的進程,可以將上面的函數傳回碼修改為
return appProcess.processName+"層級"+appProcess.importance;
其中importance是反應進程優先順序的屬性,具體請查看下錶:
在實際開發中,如果大家想獲得進程的狀態可以通過查看你想知道的進程的importance屬性。
在此我在Demo中重寫了MainActivity與NewProgress的生命週期方法,Logcat的列印日誌如下:
12-10 13:05:13.083: I/System.out(1452): MainActivity所在進程onCreate:newpackage.test層級100 前台進程
12-10 13:05:13.091: I/System.out(1452): MainActivity所在進程onStart:newpackage.test層級100 前台進程
12-10 13:05:13.095: I/System.out(1452): MainActivity所在進程onResume:newpackage.test層級100 前台進程
12-10 13:06:30.335: I/System.out(1452): MainActivity所在進程onPause:newpackage.test層級100 前台進程
12-10 13:06:30.595: I/System.out(1471): NewProgress所在進程onCreate:NewProgress.層級100 前台進程
12-10 13:06:30.595: I/System.out(1471): NewProgress所在進程onStart:NewProgress.層級100 前台進程
12-10 13:06:30.599: I/System.out(1471): NewProgress所在進程onResume:NewProgress.層級100 前台進程
12-10 13:06:30.923: I/System.out(1452): MainActivity所在進程onStop:newpackage.test層級130 可見進程(經典情境:Activity彈出對話方塊)
12-10 13:07:46.199: I/System.out(1471): NewProgress所在進程onPause:NewProgress.層級100 前台進程
12-10 13:07:46.207: I/System.out(1452): MainActivity所在進程onRestart:newpackage.test層級100 前台進程
12-10 13:07:46.211: I/System.out(1452): MainActivity所在進程onStart:newpackage.test層級100 前台進程
12-10 13:07:46.211: I/System.out(1452): MainActivity所在進程onResume:newpackage.test層級100 前台進程
12-10 13:07:46.647: I/System.out(1471): NewProgress所在進程onStop:NewProgress.層級400 後台進程
12-10 13:07:46.647: I/System.out(1471): NewProgress所在進程onDestroy:NewProgress.層級400 後台進程
要講的就這麼多,如果大家有什麼不明白的可以回複提問,如果有不對之處,也請大家指出。
Demo:http://download.csdn.net/detail/gc_gongchao/8245593
轉載請註明出處:http://blog.csdn.net/android_jiangjun/article/details/41851139