導航:首頁 > 操作系統 > android防止被kill

android防止被kill

發布時間:2022-05-11 22:12:33

android怎麼讓activity不被殺死

方法:
對於一個service,可以首先把它設為在前台運行:
public void MyService.onCreate() {
super.onCreate();
Notification notification = new Notification(android.R.drawable.my_service_icon,
"my_service_name",
System.currentTimeMillis());
PendingIntent p_intent = PendingIntent.getActivity(this, 0,
new Intent(this, MyMainActivity.class), 0);
notification.setLatestEventInfo(this, "MyServiceNotification, "MyServiceNotification is Running!", p_intent);
Log.d(TAG, String.format("notification = %s", notification));
startForeground(0x1982, notification); // notification ID: 0x1982, you can name it as you will.
}

重要設置-------------------------------
相較於/data/app下的應用,放在/system/app下的應用享受更多的特權,比如若在其Manifest.xml文件中設置persistent屬性為true,則可使其免受out-of-memory killer的影響。如應用程序'Phone'的AndroidManifest.xml文件:
<application android:name="PhoneApp"
android:persistent="true"
android:label="@string/dialerIconLabel"
android:icon="@drawable/ic_launcher_phone">
...
</application>
設置後app提升為系統核心級別,任何情況下不會被kill掉, settings->applications裡面也會屏蔽掉stop操作。

這樣設置前的log: Proc #19: adj=svc /B 4067b028 255:com.xxx.xxx/10001 (started-services)
# cat /proc/255/oom_adj

設置後的log: PERS #19: adj=core /F 406291f0 155:com.xxx.xxx/10001 (fixed)
# cat /proc/155/oom_adj
-12 # 這是CORE_SERVER_ADJ
註:init進程的oom_adj為-16(即SYSTEM_ADJ): cat /proc/1/oom_adj

Android相關部分分析:
在文件frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中有以下的代碼:
final ProcessRecord addAppLocked(ApplicationInfo info) {
ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);

if (app == null) {
app = newProcessRecordLocked(null, info, null);
mProcessNames.put(info.processName, info.uid, app);
updateLruProcessLocked(app, true, true);
}

if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
== (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
app.persistent = true;
app.maxAdj = CORE_SERVER_ADJ; // 這個常數值為-12。
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
startProcessLocked(app, "added application", app.processName);
}

return app;
}

可見要想成為core service (即app.maxAdj = CORE_SERVER_ADJ(-12)),應用程序需要FLAG_SYSTEM和FLAG_PERSISTENT兩個標志,FLAG_SYSTEM指的是應用位於/system/app下,FLAG_PERSISTENT就是指persistent屬性。

而對於frameworks/base/services/java/com/android/server/SystemServer.java,則調用
ActivityManagerService.setSystemProcess();
把自己的 app.maxAdj 設置成SYSTEM_ADJ,即-16。

原理:
Android中的進程是託管的,當系統進程空間緊張的時候,會依照優先順序自動進行進程的回收。由此帶來三個問題:
1) 回收規則: 什麼時候回收與回收哪一個?
2) 避免誤殺: 如何阻止被回收?
3) 數據恢復與保存: 被回收了怎麼辦?

Android將進程分為6個等級,它們按優先順序順序由高到低依次是:
1.前台進程( FOREGROUND_APP)
2.可視進程(VISIBLE_APP )
3. 次要服務進程(SECONDARY_SERVER )
4.後台進程 (HIDDEN_APP)
5.內容供應節點(CONTENT_PROVIDER)
6.空進程(EMPTY_APP)

② Android防止殺進程

1.在service中重寫下面的方法,這個方法有三個返回值, START_STICKY是service被kill掉後自動重寫創建 [代碼]java代碼: @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; }---------------- @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.v("TrafficService","startCommand"); flags = START_STICKY; return super.onStartCommand(intent, flags, startId); // return START_REDELIVER_INTENT; } 2.在Service的onDestroy()中重啟Service. public void onDestroy() { Intent localIntent = new Intent(); localIntent.setClass(this, MyService.class); //銷毀時重新啟動Service this.startService(localIntent); } 用qq管家殺掉進程的時候,調用的是系統自帶的強制kill功能(即settings里的),在kill時,會將應用的整個進程停掉,當然包括service在內,如果在running里將service強制kill掉,顯示進程還在。不管是kill整個進程還是只kill掉進應用的 service,都不會重新啟動service。不知道你是怎麼實現重啟的,實在是不解。 在eclipse中,用stop按鈕kill掉進程的時候,倒是會重啟service KILL問題: 1. settings 中stop service onDestroy方法中,調用startService進行Service的重啟。 2.settings中force stop 應用 捕捉系統進行廣播(action為android.intent.action.PACKAGE_RESTARTED) 3. 藉助第三方應用kill掉running task 提升service的優先順序 service開機啟動 今天我們主要來探討android怎麼讓一個service開機自動啟動功能的實現。Android手機在啟動的過程中會觸發一個Standard Broadcast Action,名字叫android.intent.action.BOOT_COMPLETED(記得只會觸發一次呀),在這里我們可以通過構建一個廣播接收者來接收這個這個action.下面我就來簡單寫以下實現的步驟: 第一步:首先創建一個廣播接收者,重構其抽象方法 onReceive(Context context, Intent intent),在其中啟動你想要啟動的Service或app。 [代碼]java代碼: import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class BootBroadcastReceiver extends BroadcastReceiver { //重寫onReceive方法 @Override public void onReceive(Context context, Intent intent) { //後邊的XXX.class就是要啟動的服務 Intent service = new Intent(context,XXXclass); context.startService(service); Log.v("TAG", "開機自動服務自動啟動....."); //啟動應用,參數為需要自動啟動的應用的包名 Intent intent = getPackageManager().getLaunchIntentForPackage(packageName); context.startActivity(intent ); } } 第二步:配置xml文件,在re ceiver接收這種添加intent-filter配置 [代碼]java代碼: <receiver android:name="BootBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"></action> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </receiver> 第三步:添加許可權 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 如何實現一個不會被殺死的進程 看Android的文檔知道,當進程長期不活動,或系統需要資源時,會自動清理門戶,殺死一些Service,和不可見的Activity等所在的進程。 但是如果某個進程不想被殺死(如數據緩存進程,或狀態監控進程,或遠程服務進程),應該怎麼做,才能使進程不被殺死。 add android:persistent="true" into the <application> section in your AndroidManifest.xml 切記,這個 不可濫用,系統中用這個的service,app一多,整個系統就完蛋了。 目前系統中有phone等非常有限的,必須一直活著的應用在試用。 提升service優先順序的方法 Android 系統對於內存管理有自己的一套方法,為了保障系統有序穩定的運信,系統內部會自動分配,控製程序的內存使用。當系統覺得當前的資源非常有限的時候,為了保 證一些優先順序高的程序能運行,就會殺掉一些他認為不重要的程序或者服務來釋放內存。這樣就能保證真正對用戶有用的程序仍然再運行。如果你的 Service 碰上了這種情況,多半會先被殺掉。但如果你增加 Service 的優先順序就能讓他多留一會,我們可以用 setForeground(true) 來設置 Service 的優先順序。 為什麼是 foreground ? 默認啟動的 Service 是被標記為 background,當前運行的 Activity 一般被標記為 foreground,也就是說你給 Service 設置了 foreground 那麼他就和正在運行的 Activity 類似優先順序得到了一定的提高。當讓這並不能保證你得 Service 永遠不被殺掉,只是提高了他的優先順序。 從Android 1.5開始,一個已啟動的service可以調用startForeground(int, Notification)將service置為foreground狀態,調用stopForeground(boolean)將service置為 background狀態。 我們會在調用startForeground(int, Notification)傳入參數notification,它會在狀態欄里顯示正在進行的foreground service。background service不會在狀態欄里顯示。 在Android 1.0中,將一個service置為foreground狀態: setForeground(true); mNM.notify(id, notification); 將一個service置為background狀態: mNM.cancel(id); setForeground(false); 對比看出,在1.0 API中調用setForeground(boolean)只是簡單的改變service的狀態,用戶不會有任何覺察。新API中強制將 notification和改變service狀態的動作綁定起來,foreground service會在狀態欄顯示,而background service不會。 Remote service controller & binding 跨進程調用Service。暫時不研究。 如何防止Android應用中的Service被系統回收? 很多朋友都在問,如何防止Android應用中的Service被系統回收?下面簡單解答一下。 對於Service被系統回收,一般做法是通過提高優先順序可以解決,在AndroidManifest.xml文件中對於intent-filter可以通過 android:priority = "1000"這個屬性設置最高優先順序,1000是最高值,如果數字越小則優先順序越低,同時實用於廣播,推薦大家如果你的應用很重要,可以考慮通過系統常用intent action來觸發。

③ android後台服務保持,不被殺死

作者:閉關寫代碼
鏈接:https://www.hu.com/question/29826231/answer/71207109
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。

強烈建議不要這么做,不僅僅從用戶角度考慮,作為Android開發者也有責任去維護Android的生態環境。現在很多Android開發工程師,主力機居然是iPhone而不是Android設備,感到相當悲哀。
從技術角度概括一下現在普遍的防殺方法

Service設置成START_STICKY,kill 後會被重啟(等待5秒左右),重傳Intent,保持與重啟前一樣
通過 startForeground將進程設置為前台進程,做前台服務,優先順序和前台應用一個級別,除非在系統內存非常缺,否則此進程不會被 kill

雙進程Service:讓2個進程互相保護,其中一個Service被清理後,另外沒被清理的進程可以立即重啟進程
QQ黑科技:在應用退到後台後,另起一個只有 1 像素的頁面停留在桌面上,讓自己保持前台狀態,保護自己不被後台清理工具殺死
在已經root的設備下,修改相應的許可權文件,將App偽裝成系統級的應用(Android4.0系列的一個漏洞,已經確認可行)
Android系統中當前進程(Process)fork出來的子進程,被系統認為是兩個不同的進程。當父進程被殺死的時候,子進程仍然可以存活,並不受影響。鑒於目前提到的在Android-Service層做雙守護都會失敗,我們可以fork出c進程,多進程守護。死循環在那檢查是否還存在,具體的思路如下(Android5.0以下可行)
用C編寫守護進程(即子進程),守護進程做的事情就是循環檢查目標進程是否存在,不存在則啟動它。
在NDK環境中將1中編寫的C代碼編譯打包成可執行文件(BUILD_EXECUTABLE)。
主進程啟動時將守護進程放入私有目錄下,賦予可執行許可權,啟動它即可。
聯系廠商,加入白名單
------------------------------------------------------
TIP: 面對各種流氓軟體後台常駐問題,建議使用「綠色守護」來解決,可是殺掉那些第三方清理工具難以清除的後台程序

④ 怎麼讓Android程序一直後台運行,像QQ一樣不被殺死

方法:
對於一個service,可以首先把它設為在前台運行:
public void MyService.onCreate() {
super.onCreate();
Notification notification = new Notification(android.R.drawable.my_service_icon,
"my_service_name",
System.currentTimeMillis());
PendingIntent p_intent = PendingIntent.getActivity(this, 0,
new Intent(this, MyMainActivity.class), 0);
notification.setLatestEventInfo(this, "MyServiceNotification, "MyServiceNotification is Running!", p_intent);
Log.d(TAG, String.format("notification = %s", notification));
startForeground(0x1982, notification); // notification ID: 0x1982, you can name it as you will.
}

重要設置-------------------------------
相較於/data/app下的應用,放在/system/app下的應用享受更多的特權,比如若在其Manifest.xml文件中設置persistent屬性為true,則可使其免受out-of-memory killer的影響。如應用程序'Phone'的AndroidManifest.xml文件:
<application android:name="PhoneApp"
android:persistent="true"
android:label="@string/dialerIconLabel"
android:icon="@drawable/ic_launcher_phone">
...
</application>
設置後app提升為系統核心級別,任何情況下不會被kill掉, settings->applications裡面也會屏蔽掉stop操作。

這樣設置前的log: Proc #19: adj=svc /B 4067b028 255:com.xxx.xxx/10001 (started-services)
# cat /proc/255/oom_adj

設置後的log: PERS #19: adj=core /F 406291f0 155:com.xxx.xxx/10001 (fixed)
# cat /proc/155/oom_adj
-12 # 這是CORE_SERVER_ADJ
註:init進程的oom_adj為-16(即SYSTEM_ADJ): cat /proc/1/oom_adj

Android相關部分分析:
在文件frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中有以下的代碼:
final ProcessRecord addAppLocked(ApplicationInfo info) {
ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);

if (app == null) {
app = newProcessRecordLocked(null, info, null);
mProcessNames.put(info.processName, info.uid, app);
updateLruProcessLocked(app, true, true);
}

if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
== (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
app.persistent = true;
app.maxAdj = CORE_SERVER_ADJ; // 這個常數值為-12。
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
startProcessLocked(app, "added application", app.processName);
}

return app;
}

可見要想成為core service (即app.maxAdj = CORE_SERVER_ADJ(-12)),應用程序需要FLAG_SYSTEM和FLAG_PERSISTENT兩個標志,FLAG_SYSTEM指的是應用位於/system/app下,FLAG_PERSISTENT就是指persistent屬性。

而對於frameworks/base/services/java/com/android/server/SystemServer.java,則調用
ActivityManagerService.setSystemProcess();
把自己的 app.maxAdj 設置成SYSTEM_ADJ,即-16。

原理:
Android中的進程是託管的,當系統進程空間緊張的時候,會依照優先順序自動進行進程的回收。由此帶來三個問題:
1) 回收規則: 什麼時候回收與回收哪一個?
2) 避免誤殺: 如何阻止被回收?
3) 數據恢復與保存: 被回收了怎麼辦?

Android將進程分為6個等級,它們按優先順序順序由高到低依次是:
1.前台進程( FOREGROUND_APP)
2.可視進程(VISIBLE_APP )
3. 次要服務進程(SECONDARY_SERVER )
4.後台進程 (HIDDEN_APP)
5.內容供應節點(CONTENT_PROVIDER)
6.空進程(EMPTY_APP)

特徵:
1.如果一個進程裡面同時包含service和可視的activity,那麼這個進程應該歸於可視進程,而不是service進程。
2.另外,如果其他進程依賴於它的話,一個進程的等級可以提高。例如,一個A進程里的service被綁定到B進程里的組件上,進程A將總被認為至少和B進程一樣重要。
3.系統中的phone服務被劃分到前台進程而不是次要服務進程.

在android中,進程的oom_adj值也就代表了它的優先順序。oom_adj值越高代表該進程優先順序越低。文件/init.rc中有以下屬性設置:
setprop ro.FOREGROUND_APP_ADJ 0
setprop ro.VISIBLE_APP_ADJ 1
setprop ro.SECONDARY_SERVER_ADJ 2
setprop ro.HIDDEN_APP_MIN_ADJ 7
setprop ro.CONTENT_PROVIDER_ADJ 14
setprop ro.EMPTY_APP_ADJ 15
/init.rc中,將PID為1的進程(init進程)的oom_adj設置為SYSTEM_ADJ(-16):
# Set init its forked children's oom_adj.
write /proc/1/oom_adj -16

查看本機設置:
cat /sys/mole/lowmemorykiller/parameters/adj
0,1,2,7,14,15

回收時機:
文件/init.rc中:
setprop ro.FOREGROUND_APP_MEM 1536 // 6M
setprop ro.VISIBLE_APP_MEM 2048 // 8M
setprop ro.SECONDARY_SERVER_MEM 4096 // 16M
setprop ro.HIDDEN_APP_MEM 5120 // 20M
setprop ro.CONTENT_PROVIDER_MEM 5632 // 22.4M
setprop ro.EMPTY_APP_MEM 6144 // 24M
這些數字也就是對應的內存閾值,一旦低於該值,Android便開始按順序關閉相應等級的進程。
注意這些數字的單位是page: 1 page = 4 kB。所以上面的六個數字對應的就是(MB): 6,8,16,20,22,24。

查看現在的內存閾值設置:
cat /sys/mole/lowmemorykiller/parameters/minfree

要想重新設置該值(對應不同的需求):
echo "1536,2048,4096,5120,15360,23040">/sys/mole/lowmemorykiller/parameters/minfree
這樣當可用內存低於90MB的時候便開始殺死"空進程",而當可用內存低於60MB的時候才開始殺死"內容供應節點"類進程。

具體的回收實現在ActivityManagerService.java中的函數trimApplications():
1.首先移除package已被卸載的無用進程;
2.基於進程當前狀態,更新oom_adj值,然後進行以下操作:
1) 移除沒有activity在運行的進程;
2) 如果AP已經保存了所有的activity狀態,結束這個AP。
3. 最後,如果目前還是有很多activities 在運行,那麼移除那些activity狀態已經保存好的activity。

更新oom_adj的值:
在ActivityManagerService.java文件的ComputeOomAdjLocked() 中計算出進程的oom_adj,例如:
if (app == TOP_APP) {
// The last app on the list is the foreground app.
adj = FOREGROUND_APP_ADJ;
app.adjType = "top-activity";
}

Android kernel中的low memory killer
Android的Low Memory Killer根據需要(當系統內存短缺時)殺死進程釋放其內存,源代碼在kernel/drivers/misc/lowmemorykiller.c中。簡單說,就是尋找一個最合適的進程殺死,從而釋放它佔用的內存。
最合適的進程是:
• oom_adj越大
• 佔用物理內存越多

一旦一個進程被選中,內核會發送SIGKILL信號將之殺死:
for_each_process(p) {
……
if(selected == NULL || p->oomkilladj > selected->oomkilladj ||
(p->oomkilladj == selected->oomkilladj && tasksize > selected_tasksize))
{
selected = p;
}
}
if(selected != NULL) {
force_sig(SIGKILL, selected);
}

查看LRU列表:adb shell mpsys activity
當activitydemo在前台時:
包含Service的進程的優先順序比較高,在computeOomAdjLocked中將其分為了兩小類:
static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
if (adj > SECONDARY_SERVER_ADJ) {
adj = SECONDARY_SERVER_ADJ;
app.adjType = "started-services";
app.hidden = false;
}
}
if (adj > SECONDARY_SERVER_ADJ) {
app.adjType = "started-bg-services";
}
完全讓進程不被kill是不可能的,我們可以通過一些操作,使進程被kill的幾率變小:
1) 提高進程的優先順序:
* 後台操作採用運行於前台的Service形式,因為一個運行著service的進程比一個運行著後台activity的等級高;
* 按back鍵使得進程中的activity在後台運行而不是destory,需重載back按鍵(沒有任何activity在運行的進程優先被殺).
* 依賴於其他優先順序高的進程;

2) 強制修改進程屬性:
* 在進程中設置:setPersistent(true);
* 在Manifest文件中設置(如上)。

⑤ 想讓android應用常駐後台,不被殺死,各位大神有什麼高招

方法: 對於一個service,可以首先把它設為在前台運行: public void MyService.onCreate() { super.onCreate(); Notification notification = new Notification(android.R.drawable.my_service_icon, "my_service_name", System.currentTimeMillis()); PendingIntent p_intent = PendingIntent.getActivity(this, 0, new Intent(this, MyMainActivity.class), 0); notification.setLatestEventInfo(this, "MyServiceNotification, "MyServiceNotification is Running!", p_intent); Log.d(TAG, String.format("notification = %s", notification)); startForeground(0x1982, notification); // notification ID: 0x1982, you can name it as you will. } 重要設置------------------------------- 相較於/data/app下的應用,放在/system/app下的應用享受更多的特權,比如若在其Manifest.xml文件中設置persistent屬性為true,則可使其免受out-of-memory killer的影響。如應用程序'Phone'的AndroidManifest.xml文件: <application android:name="PhoneApp" android:persistent="true" android:label="@string/dialerIconLabel" android:icon="@drawable/ic_launcher_phone"> ... </application> 設置後app提升為系統核心級別,任何情況下不會被kill掉, settings->applications裡面也會屏蔽掉stop操作。 這樣設置前的log: Proc #19: adj=svc /B 4067b028 255:com.xxx.xxx/10001 (started-services) # cat /proc/255/oom_adj 設置後的log: PERS #19: adj=core /F 406291f0 155:com.xxx.xxx/10001 (fixed) # cat /proc/155/oom_adj -12 # 這是CORE_SERVER_ADJ 註:init進程的oom_adj為-16(即SYSTEM_ADJ): cat /proc/1/oom_adj Android相關部分分析: 在文件frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中有以下的代碼: final ProcessRecord addAppLocked(ApplicationInfo info) { ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); if (app == null) { app = newProcessRecordLocked(null, info, null); mProcessNames.put(info.processName, info.uid, app); updateLruProcessLocked(app, true, true); } if ((info.flags&(ApplicationInfo.FLAG_SYSTEMApplicationInfo.FLAG_PERSISTENT)) == (ApplicationInfo.FLAG_SYSTEMApplicationInfo.FLAG_PERSISTENT)) { app.persistent = true; app.maxAdj = CORE_SERVER_ADJ; // 這個常數值為-12。 } if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { mPersistentStartingProcesses.add(app); startProcessLocked(app, "added application", app.processName); } return app; } 可見要想成為core service (即app.maxAdj = CORE_SERVER_ADJ(-12)),應用程序需要FLAG_SYSTEM和FLAG_PERSISTENT兩個標志,FLAG_SYSTEM指的是應用位於/system/app下,FLAG_PERSISTENT就是指persistent屬性。 而對於frameworks/base/services/java/com/android/server/SystemServer.java,則調用 ActivityManagerService.setSystemProcess(); 把自己的 app.maxAdj 設置成SYSTEM_ADJ,即-16。 原理: Android中的進程是託管的,當系統進程空間緊張的時候,會依照優先順序自動進行進程的回收。由此帶來三個問題: 1) 回收規則: 什麼時候回收與回收哪一個? 2) 避免誤殺: 如何阻止被回收? 3) 數據恢復與保存: 被回收了怎麼辦? Android將進程分為6個等級,它們按優先順序順序由高到低依次是: 1.前台進程( FOREGROUND_APP) 2.可視進程(VISIBLE_APP ) 3. 次要服務進程(SECONDARY_SERVER ) 4.後台進程 (HIDDEN_APP) 5.內容供應節點(CONTENT_PROVIDER) 6.空進程(EMPTY_APP) 特徵: 1.如果一個進程裡面同時包含service和可視的activity,那麼這個進程應該歸於可視進程,而不是service進程。 2.另外,如果其他進程依賴於它的話,一個進程的等級可以提高。例如,一個A進程里的service被綁定到B進程里的組件上,進程A將總被認為至少和B進程一樣重要。 3.系統中的phone服務被劃分到前台進程而不是次要服務進程. 在android中,進程的oom_adj值也就代表了它的優先順序。oom_adj值越高代表該進程優先順序越低。文件/init.rc中有以下屬性設置: setprop ro.FOREGROUND_APP_ADJ 0 setprop ro.VISIBLE_APP_ADJ 1 setprop ro.SECONDARY_SERVER_ADJ 2 setprop ro.HIDDEN_APP_MIN_ADJ 7 setprop ro.CONTENT_PROVIDER_ADJ 14 setprop ro.EMPTY_APP_ADJ 15 /init.rc中,將PID為1的進程(init進程)的oom_adj設置為SYSTEM_ADJ(-16): # Set init its forked children's oom_adj. write /proc/1/oom_adj -16 查看本機設置: cat /sys/mole/lowmemorykiller/parameters/adj 0,1,2,7,14,15 回收時機: 文件/init.rc中: setprop ro.FOREGROUND_APP_MEM 1536 // 6M setprop ro.VISIBLE_APP_MEM 2048 // 8M setprop ro.SECONDARY_SERVER_MEM 4096 // 16M setprop ro.HIDDEN_APP_MEM 5120 // 20M setprop ro.CONTENT_PROVIDER_MEM 5632 // 22.4M setprop ro.EMPTY_APP_MEM 6144 // 24M 這些數字也就是對應的內存閾值,一旦低於該值,Android便開始按順序關閉相應等級的進程。 注意這些數字的單位是page: 1 page = 4 kB。所以上面的六個數字對應的就是(MB): 6,8,16,20,22,24。 查看現在的內存閾值設置: cat /sys/mole/lowmemorykiller/parameters/minfree 要想重新設置該值(對應不同的需求): echo "1536,2048,4096,5120,15360,23040">/sys/mole/lowmemorykiller/parameters/minfree 這樣當可用內存低於90MB的時候便開始殺死"空進程",而當可用內存低於60MB的時候才開始殺死"內容供應節點"類進程。 具體的回收實現在ActivityManagerService.java中的函數trimApplications(): 1.首先移除package已被卸載的無用進程; 2.基於進程當前狀態,更新oom_adj值,然後進行以下操作: 1) 移除沒有activity在運行的進程; 2) 如果AP已經保存了所有的activity狀態,結束這個AP。 3. 最後,如果目前還是有很多activities 在運行,那麼移除那些activity狀態已經保存好的activity。 更新oom_adj的值: 在ActivityManagerService.java文件的ComputeOomAdjLocked() 中計算出進程的oom_adj,例如: if (app == TOP_APP) { // The last app on the list is the foreground app. adj = FOREGROUND_APP_ADJ; app.adjType = "top-activity"; } Android kernel中的low memory killer Android的Low Memory Killer根據需要(當系統內存短缺時)殺死進程釋放其內存,源代碼在kernel/drivers/misc/lowmemorykiller.c中。簡單說,就是尋找一個最合適的進程殺死,從而釋放它佔用的內存。 最合適的進程是: • oom_adj越大 • 佔用物理內存越多 一旦一個進程被選中,內核會發送SIGKILL信號將之殺死: for_each_process(p) { …… if(selected == NULL p->oomkilladj > selected->oomkilladj (p->oomkilladj == selected->oomkilladj && tasksize > selected_tasksize)) { selected = p; } } if(selected != NULL) { force_sig(SIGKILL, selected); } 查看LRU列表:adb shell mpsys activity 當activitydemo在前台時: 包含Service的進程的優先順序比較高,在computeOomAdjLocked中將其分為了兩小類: static final int MAX_SERVICE_INACTIVITY = 30*60*1000; if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { if (adj > SECONDARY_SERVER_ADJ) { adj = SECONDARY_SERVER_ADJ; app.adjType = "started-services"; app.hidden = false; } } if (adj > SECONDARY_SERVER_ADJ) { app.adjType = "started-bg-services"; } 完全讓進程不被kill是不可能的,我們可以通過一些操作,使進程被kill的幾率變小: 1) 提高進程的優先順序: * 後台操作採用運行於前台的Service形式,因為一個運行著service的進程比一個運行著後台activity的等級高; * 按back鍵使得進程中的activity在後台運行而不是destory,需重載back按鍵(沒有任何activity在運行的進程優先被殺). * 依賴於其他優先順序高的進程; 2) 強制修改進程屬性: * 在進程中設置:setPersistent(true); * 在Manifest文件中設置(如上)。

⑥ android開發怎麼讓個推服務不被手機系統殺掉

1.在service中重寫下面的方法,這個方法有三個返回值,START_STICKY是service被kill掉後自動重寫創建[代碼]java代碼:@(Intentintent,intflags,intstartId){returnSTART_STICKY;}----------------@(Intentintent,intflags,intstartId){//TODOAuto-generatedmethodstubLog.v("TrafficService","startCommand");flags=START_STICKY;returnsuper.onStartCommand(intent,flags,startId);//returnSTART_REDELIVER_INTENT;}2.在Service的onDestroy()中重啟Service.publicvoidonDestroy(){IntentlocalIntent=newIntent();localIntent.setClass(this,MyService.class);//銷毀時重新啟動Servicethis.startService(localIntent);}用 管家殺掉進程的時候,調用的是系統自帶的強制kill功能(即settings里的),在kill時,會將應用的整個進程停掉,當然包括service在內,如果在running里將service強制kill掉,顯示進程還在。不管是kill整個進程還是只kill掉進應用的service,都不會重新啟動service。不知道你是怎麼實現重啟的,實在是不解。在eclipse中,用stop按鈕kill掉進程的時候,倒是會重啟serviceKILL問題:1.settings中stopserviceonDestroy方法中,調用startService進行Service的重啟。2.settings中forcestop應用捕捉系統進行廣播(action為android.intent.action.PACKAGE_RESTARTED)3.藉助第三方應用kill掉runningtask提升service的優先順序service開機啟動今天我們主要來探討android怎麼讓一個service開機自動啟動功能的實現。Android手機在啟動的過程中會觸發一個StandardBroadcastAction,名字叫android.intent.action.BOOT_COMPLETED(記得只會觸發一次呀),在這里我們可以通過構建一個廣播接收者來接收這個這個action.下面我就來簡單寫以下實現的步驟:第一步:首先創建一個廣播接收者,重構其抽象方法onReceive(Contextcontext,Intentintent),在其中啟動你想要啟動的Service或app。[代碼]java代碼:importandroid.content.BroadcastReceiver;importandroid.content.Context;importandroid.content.Intent;importandroid.util.Log;{//重寫onReceive方法@OverridepublicvoidonReceive(Contextcontext,Intentintent){//後邊的XXX.class就是要啟動的服務Intentservice=newIntent(context,XXXclass);context.startService(service);Log.v("TAG","開機自動服務自動啟動..");//啟動應用,參數為需要自動啟動的應用的包名Intentintent=getPackageManager().getLaunchIntentForPackage(packageName);context.startActivity(intent);}}第二步:配置xml文件,在receiver接收這種添加intent-filter配置[代碼]java代碼:第三步:添加許可權如何實現一個不會被殺死的進程看Android的文檔知道,當進程長期不活動,或系統需要資源時,會自動清理門戶,殺死一些Service,和不可見的Activity等所在的進程。但是如果某個進程不想被殺死(如數據緩存進程,或狀態監控進程,或遠程服務進程),應該怎麼做,才能使進程不被殺死。addandroid:persistent="true".xml切記,這個不可濫用,系統中用這個的service,app一多,整個系統就完蛋了。目前系統中有phone等非常有限的,必須一直活著的應用在試用。提升service優先順序的方法Android系統對於內存管理有自己的一套方法,為了保障系統有序穩定的運信,系統內部會自動分配,控製程序的內存使用。當系統覺得當前的資源非常有限的時候,為了保證一些優先順序高的程序能運行,就會殺掉一些他認為不重要的程序或者服務來釋放內存。這樣就能保證真正對用戶有用的程序仍然再運行。如果你的Service碰上了這種情況,多半會先被殺掉。但如果你增加Service的優先順序就能讓他多留一會,我們可以用setForeground(true)來設置Service的優先順序。為什麼是foreground?默認啟動的Service是被標記為background,當前運行的Activity一般被標記為foreground,也就是說你給Service設置了foreground那麼他就和正在運行的Activity類似優先順序得到了一定的提高。當讓這並不能保證你得Service永遠不被殺掉,只是提高了他的優先順序。從Android1.5開始,一個已啟動的service可以調用startForeground(int,Notification)將service置為foreground狀態,調用stopForeground(boolean)將service置為background狀態。我們會在調用startForeground(int,Notification)傳入參數notification,它會在狀態欄里顯示正在進行的foregroundservice。backgroundservice不會在狀態欄里顯示。在Android1.0中,將一個service置為foreground狀態:setForeground(true);mNM.notify(id,notification);將一個service置為background狀態:mNM.cancel(id);setForeground(false);對比看出,在1.0API中調用setForeground(boolean)只是簡單的改變service的狀態,用戶不會有任何覺察。新API中強制將notification和改變service狀態的動作綁定起來,foregroundservice會在狀態欄顯示,而backgroundservice不會。Remoteservicecontroller&binding跨進程調用Service。暫時不研究。如何防止Android應用中的Service被系統回收?很多朋友都在問,如何防止Android應用中的Service被系統回收?下面簡單解答一下。對於Service被系統回收,一般做法是通過提高優先順序可以解決,在AndroidManifest.xml文件中對於intent-filter可以通過android:priority="1000"這個屬性設置最高優先順序,1000是最高值,如果數字越小則優先順序越低,同時實用於廣播,推薦大家如果你的應用很重要,可以考慮通過系統常用intentaction來觸發。

⑦ Android下怎麼寫一個永遠不會被KILL掉的進程/服務

Android 系統對於內存管理有自己的一套方法,為了保障系統有序穩定的運信,系統內部會自動分配,控製程序的內存使用。當系統覺得當前的資源非常有限的時候,為了保證一些優先順序高的程序能運行,就會殺掉一些他認為不重要的程序或者服務來釋放內存。這樣就能保證真正對用戶有用的程序仍然再運行。如果你的 Service 碰上了這種情況,多半會先被殺掉。但如果你增加 Service 的優先順序就能讓他多留一會,我們可以用 setForeground(true) 來設置 Service 的優先順序。

為什麼是 foreground ? 默認啟動的 Service 是被標記為 background,當前運行的 Activity 一般被標記為 foreground,也就是說你給 Service 設置了 foreground 那麼他就和正在運行的 Activity 類似優先順序得到了一定的提高。當讓這並不能保證你得 Service 永遠不被殺掉,只是提高了他的優先順序。

有一個方法可以給你更清晰的演示,進入 $SDK/tools 運行命令

代碼如下:

# adb shell mpsys activity|grep oom_adj

Running Norm Proc # 6: oom_adj= 0 ProcessRecord{43635cf0 12689:com.roiding.netraffic/10028}

Running Norm Proc # 5: oom_adj= 7 ProcessRecord{436feda0 12729:com.android.browser/10006}

Running Norm Proc # 4: oom_adj= 8 ProcessRecord{4367e838 12761:android.process.acore/10016}

Running Norm Proc # 3: oom_adj= 8 ProcessRecord{43691cd8 12754:com.google.process.gapps/10000}

Running PERS Proc # 1: oom_adj=-12 ProcessRecord{43506750 5941:com.android.phone/1001}

Running PERS Proc # 0: oom_adj=-100 ProcessRecord{4348fde0 5908:system/1000}

代碼如下:

返回的一大堆東西,觀察 oom_adj 的值,如果是大於 8 一般就是屬於 backgroud 隨時可能被幹掉,數值越小證明優先順序越高,被幹掉的時間越晚。你看phone的程序是 -12 說明電話就是電話,其他什麼都幹了了,也的能接電話對吧。另外還有一個 -100 的,更邪乎因為是 system 如果他也完蛋了,你得系統也就掛了。

我是天王蓋地虎的分割線

從Android 1.5開始,一個已啟動的service可以調用startForeground(int, Notification)將service置為foreground狀態,調用stopForeground(boolean)將service置為 background狀態。

我們會在調用startForeground(int, Notification)傳入參數notification,它會在狀態欄里顯示正在進行的foreground service。background service不會在狀態欄里顯示。

在Android 1.0中,將一個service置為foreground狀態:

setForeground(true);

mNM.notify(id, notification);

將一個service置為background狀態:

mNM.cancel(id);

setForeground(false);

對比看出,在1.0 API中調用setForeground(boolean)只是簡單的改變service的狀態,用戶不會有任何覺察。新API中強制將 notification和改變service狀態的動作綁定起來,foreground service會在狀態欄顯示,而background service不會。

通過在androidmanifest.xml中的application標簽中加入android:persistent="true"屬性後的確就能夠達到保證該應用程序所在進程不會被LMK殺死。但有個前提就是應用程序必須是系統應用,也就是說應用程序不能採用通常的安裝方式。必須將應用程序的apk包直接放到/system/app目錄下。而且必須重啟系統後才能生效。

除了一般的幾種優先順序外,還存在著coreserver,system這樣的永遠不會被LMK回收的優先順序。系統中的電話應用就是coreserver優先順序的。

通過查看源代碼可以知道,只有應用程序的flag同時為FLAG_SYSTEM和FLAG_PERSISTENT時,才會被設置為coreserver優先順序

if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))

== (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {

app.persistent = true;

app.maxAdj = CORE_SERVER_ADJ;

}

FLAG_SYSTEM在應用程序apk放在/system/app下時會被設置。所以才會出現只設置android:persistent="true"仍然會被殺死的情況。

測試時發現,將應用程序放到/system/app後不重啟系統,仍然會被識別為普通的進程。當系統重新啟動時,會在一開始就啟動該進程並把它優先順序設置為coreserver。

通過mpsys activity命令能夠很明顯的看出其中差別。

⑧ 如何讓自己的Android程序永不被系統kill

一般來說,在Android系統中,當某進程較長時間不活動,或系統資源比較緊時,該進程可能被系統kill掉,以此來回收一些資源。Android系統會根據進程的優先順序來選擇性地殺死一些進程,優先順序從高到低依次是:
1. 前台進程(Foreground Process)
2. 可視進程(Visible Process)
3. 服務進程(Service Process)
4. 後台進程(Background Process)
5. 空進程(Empty Process)

1. 前台進程(Foreground Process)是指當前的活動進程,即那些有窗口、控制項的,正與用戶進行交互的應用程序進程。Android會努力嘗試從其它進程回收系統資源來保持其響應。
2. 可見進程(Visible Process)是指那些可見的活動進程,但是當前它不在前台運行,不能對用戶事件作出反映。比如一個程序A正在前台運行,接著又啟動了另一個程序B,程序B的窗口把程序A的窗口完全或部分遮擋,那麼,程序A現在就屬於可見進程了。一般來說,只有在系統資源十分缺乏的情況下,為了保證活動進程的運行,系統才會終止它。
3. 服務進程(Service Process)是指那些沒有可見界面的進程,它們不能直接與用戶進行交互。前台進程(通常是一個Activity)變為非活動時,會暫停運行;但服務進程可在後台保持運行,因此如果要保持進程在轉到後台後也能運行,就必需啟動一個Service。但是一旦前台進程需要資源時,Service就很容易被系統給kill掉。通常,默認情況下Service被kill掉後會自動重啟,但是重啟後並不能保證恢復先前的環境;如果不需要Service自動重啟,調用stopSelf()函數即可。
4. 後台進程(Background Process)是指不可見的,且沒有任何正在運行的服務的活動的進程。通常後台進程會比較多,Android將按「最後一個被看到,第一個終止」的方式來終止它們,從而為前台進程提供資源。
5. 對於空進程,Android為了提高系統的整體性能,經常在在應用程序的生存期結束後仍然把它們保存在內存中,當該程序被再次啟動時,可以加快啟動速度。這類進程會根據需要被定期終止。

由上可知,要想自己所寫的Service不輕易被系統在回收資源時kill掉,正常的做法是盡量提高程序的優先順序,如調用startForeground(true)。因為Service啟動時默認被標記為Background,當前運行的Activity被標記為Foreground,當將Service設置為Foreground後,它的優先順序就與正在運行的Activity類似,但是這也不能保證它不被系統kill。
如果我們要寫一個監控程序,監測其它程序的運行,那麼該怎麼辦呢?我們必需保證我們的程序不會因回收資源而kill。顯然,優先順序為2-5的進程都不可靠,作為監控程序,其優先順序也不可能為1。
這樣看上去,貌似沒有辦法了……別急,繼續看下面……

解決方法:
簡單地說,就是將自己寫的Service變成Core Service,即將自己寫的程序提升為系統級別的程序,這樣在任何情況下它都不會被kill掉。
要想自己寫的Service提升為Core Service,應用程序需要設置兩個標志:FLAG_PERSISTENT和FLAG_SYSTEM。

具體做法如下:
1. 設置FLAG_PERSISTENT:在AndroidManifest.xml文件中,加入android:persistent="true" ;

2. 設置FLAG_SYSTEM:將你寫的應用程序放到/system/app/目錄下即可。具體操作如下:
A. 使用Cygwin或cmd進入你工程所在的bin目錄中,然後執行如下兩條命令:
adb remount
adb push yourpackage.apk /system/app/
命令adb remount是為了獲取系統目錄的臨時操作許可權,然後使用push命令將自己寫的程序包上傳到系統應用程序目錄中。

B. 重啟手機。開機後,在應用列表中就可以看到你寫的程序了。
需要說明的是:系統程序不能像非系統程序那樣使用adb install yourpackage.apk來安裝apk包,我們只需要將apk包拷貝到/system/app/目錄下重啟即可。如果使用adb install的方式,那麼FLAG_SYSTEM標志不會被設置,FLAG_PERSISTENT標志也將不起任何作用。

C. 如果需要卸載自己寫的系統應用程序,可執行如下命令:
adb remount
adb shell rm /system/app/yourpackage.apk

另外,還需要說明的是,如果想在模擬器中加入自己寫的系統級應用程序,好像不行,因為將apk復制到/system/app/下後,還必需重啟,但模擬器一重啟,系統目錄也將恢復初始狀態。不過網上好像有人做到了,方法也很簡單,就是將Android源碼相應地方稍改下,然後重新編譯……

現在,我們就可以讓我們的程序為所欲為了~

安卓怎麼保證service不被殺死

Service簡介 Service是在一段不定的時間運行在後台,不和用戶交互應用組件。每個Service必須在manifest中 通過<service>來聲明。可以通過contect.startservice和contect.bindserverice來啟動。和其他的應用組件一樣,運行在進程的主線程中。這就是說如果service需要很多耗時或者阻塞的操作,需要在其子線程中實現(或者用系統提供的IntentService,它繼承了Service,它處理數據是用自身新開的線程)。【當然你也可以在新的線程中startService,這樣Service就不是在MainThread了】 本地服務 Local Service 用於應用程序內部 它可以啟動並運行,直至有人停止了它或它自己停止。在這種方式下,它以調用Context.startService()啟動,而以調用Context.stopService()結束。它可以調用Service.stopSelf() 或 Service.stopSelfResult()來自己停止。不論調用了多少次startService()方法,你只需要調用一次stopService()來停止服務。 【用於實現應用程序自己的一些耗時任務,比如查詢升級信息,並不佔用應用程序比如Activity所屬線程,而是單開線程後台執行,這樣用戶體驗比較好】 遠程服務 Remote Service 用於android系統內部的應用程序之間 它可以通過自己定義並暴露出來的介面進行程序操作。客戶端建立一個到服務對象的連接,並通過那個連接來調用服務。連接以調用Context.bindService()方法建立,以調用 Context.unbindService()關閉。多個客戶端可以綁定至同一個服務。如果服務此時還沒有載入,bindService()會先載入它。 【可被其他應用程序復用,比如天氣預報服務,其他應用程序不需要再寫這樣的服務,調用已有的即可】 1,Service的生命周期 2,Service運行方式 以startService()啟動服務,系統將通過傳入的Intent在底層搜索相關符合Intent裡面信息的service。如果服務沒有啟動則先運行onCreate,然後運行onStartCommand (可在裡面處理啟動時傳過來的Intent和其他參數),直到明顯調用stopService或者stopSelf才將停止Service。無論運行startService多少次,只要調用一次stopService或者stopSelf,Service都會停止。使用stopSelf(int)方法可以保證在處理好intent後再停止。onStartCommand ,在2.0後被引入用於service的啟動函數,2.0之前為public void onStart(Intent intent, int startId) 。 以bindService()方法啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止。onBind()只有採用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用Context.bindService()方法並不會導致該方法被多次調用。採用Context.bindService()方法啟動服務時只能調用onUnbind()方法解除調用者與服務解除,服務結束時會調用onDestroy()方法。 3,擁有service的進程具有較高的優先順序 官方文檔告訴我們,Android系統會盡量保持擁有service的進程運行,只要在該service已經被啟動(start)或者客戶端連接(bindService)到它。當內存不足時,需要保持,擁有service的進程具有較高的優先順序。 1. 如果service正在調用onCreate,onStartCommand或者onDestory方法,那麼用於當前service的進程則變為前台進程以避免被killed。 2. 如果當前service已經被啟動(start),擁有它的進程則比那些用戶可見的進程優先順序低一些,但是比那些不可見的進程更重要,這就意味著service一般不會被killed. 3. 如果客戶端已經連接到service (bindService),那麼擁有Service的進程則擁有最高的優先順序,可以認為service是可見的。 4. 如果service可以使用startForeground(int, Notification)方法來將service設置為前台狀態,那麼系統就認為是對用戶可見的,並不會在內存不足時killed。 5. 如果有其他的應用組件作為Service,Activity等運行在相同的進程中,那麼將會增加該進程的重要性。 保證service不被殺掉 onStartCommand方法,返回START_STICKY StartCommond幾個常量參數簡介: 1、START_STICKY 在運行onStartCommand後service進程被kill後,那將保留在開始狀態,但是不保留那些傳入的intent。不久後service就會再次嘗試重新創建,因為保留在開始狀態,在創建 service後將保證調用onstartCommand。如果沒有傳遞任何開始命令給service,那將獲取到null的intent。 2、START_NOT_STICKY 在運行onStartCommand後service進程被kill後,並且沒有新的intent傳遞給它。Service將移出開始狀態,並且直到新的明顯的方法(startService)調用才重新創建。因為如果沒有傳遞任何未決定的intent那麼service是不會啟動,也就是期間onstartCommand不會接收到任何null的intent。 3、START_REDELIVER_INTENT 在運行onStartCommand後service進程被kill後,系統將會再次啟動service,並傳入最後一個intent給onstartCommand。直到調用stopSelf(int)才停止傳遞intent。如果在被kill後還有未處理好的intent,那被kill後服務還是會自動啟動。因此onstartCommand不會接收到任何null的intent。 [java] view plain @Override public int onStartCommand(Intent intent, int flags, int startId) { flags = START_STICKY; return super.onStartCommand(intent, flags, startId); } 【結論】 手動返回START_STICKY,親測當service因內存不足被kill,當內存又有的時候,service又被重新創建,比較不錯,但是不能保證任何情況下都被重建,比如進程被幹掉了.... 提升service優先順序 在AndroidManifest.xml文件中對於intent-filter可以通過android:priority = "1000"這個屬性設置最高優先順序,1000是最高值,如果數字越小則優先順序越低,同時適用於廣播。 [java] view plain <service android:name="com.dbjtech.acbxt.waiqin.UploadService" android:enabled="true" > <intent-filter android:priority="1000" > <action android:name="com.dbjtech.myservice" /> </intent-filter> </service> 【結論】目前看來,priority這個屬性貌似只適用於broadcast,對於Service來說可能無效 提升service進程優先順序 Android中的進程是託管的,當系統進程空間緊張的時候,會依照優先順序自動進行進程的回收。Android將進程分為6個等級,它們按優先順序順序由高到低依次是: 1.前台進程( FOREGROUND_APP) 2.可視進程(VISIBLE_APP ) 3. 次要服務進程(SECONDARY_SERVER ) 4.後台進程 (HIDDEN_APP) 5.內容供應節點(CONTENT_PROVIDER) 6.空進程(EMPTY_APP) 當service運行在低內存的環境時,將會kill掉一些存在的進程。因此進程的優先順序將會很重要,可以使用startForeground 將service放到前台狀態。這樣在低內存時被kill的幾率會低一些。 在onStartCommand方法內添加如下代碼: [java] view plain Notification notification = new Notification(R.drawable.ic_launcher, getString(R.string.app_name), System.currentTimeMillis()); PendingIntent pendingintent = PendingIntent.getActivity(this, 0, new Intent(this, AppMain.class), 0); notification.setLatestEventInfo(this, "uploadservice", "請保持程序在後台運行", pendingintent); <span style="color:#ff0000;"> startForeground(0x111, notification);</span> 注意在onDestroy里還需要stopForeground(true),運行時在下拉列表會看到自己的APP在: 【結論】如果在極度極度低內存的壓力下,該service還是會被kill掉,並且不一定會restart onDestroy方法里重啟service service +broadcast 方式,就是當service走ondestory的時候,發送一個自定義的廣播,當收到廣播的時候,重新啟動service; [java] view plain <receiver android:name="com.dbjtech.acbxt.waiqin.BootReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.USER_PRESENT" /> <action android:name="com.dbjtech.waiqin.destroy" />//這個就是自定義的action </intent-filter> </receiver> 在onDestroy時: [java] view plain @Override public void onDestroy() { stopForeground(true); Intent intent = new Intent("com.dbjtech.waiqin.destroy"); sendBroadcast(intent); super.onDestroy(); } 在BootReceiver里 [java] view plain public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("com.dbjtech.waiqin.destroy")) { //TODO //在這里寫重新啟動service的相關操作 startUploadService(context); } } } 也可以直接在onDestroy()里startService [java] view plain @Override public void onDestroy() { Intent sevice = new Intent(this, MainService.class); this.startService(sevice); super.onDestroy(); } 【結論】當使用類似口口管家等第三方應用或是在setting里-應用-強制停止時,APP進程可能就直接被幹掉了,onDestroy方法都進不來,所以還是無法保證~.~ Application加上Persistent屬性 看Android的文檔知道,當進程長期不活動,或系統需要資源時,會自動清理門戶,殺死一些Service,和不可見的Activity等所在的進程。但是如果某個進程不想被殺死(如數據緩存進程,或狀態監控進程,或遠程服務進程),可以這么做: [java] view plain <application android:name="com.test.Application" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" <span style="color:#ff0000;"> android:persistent="true"</span> android:theme="@style/AppTheme" > </application> 【結論】據說這個屬性不能亂設置,不過設置後,的確發現優先順序提高不少,或許是相當於系統級的進程,但是還是無法保證存活 監聽系統廣播判斷Service狀態 通過系統的一些廣播,比如:手機重啟、界面喚醒、應用狀態改變等等監聽並捕獲到,然後判斷我們的Service是否還存活,別忘記加許可權啊。 [java] view plain <receiver android:name="com.dbjtech.acbxt.waiqin.BootReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.USER_PRESENT" /> <action android:name="android.intent.action.PACKAGE_RESTARTED" /> <action android:name="com.dbjtech.waiqin.destroy" /> </intent-filter> </receiver> BroadcastReceiver中: [java] view plain @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { System.out.println("手機開機了...."); startUploadService(context); } if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) { startUploadService(context); } } 【結論】這也能算是一種措施,不過感覺監聽多了會導致Service很混亂,帶來諸多不便 將APK安裝到/system/app,變身系統級應用 這個辦法不推薦使用,因為如果你的APP如果是給用戶使用的,那就不合適了,我是為了給測試的妹子來用,這個APP的目的也是很簡單,打開後開啟Service並且能保證一直在後台駐留,開機自啟動。但是昨天發現如果她的HuaWei手機長時間關閉, 再重新打開時,我們應用的Service不會自啟動,貌似廣播收不到了~一怒之下,打算搞成系統應用。 前提: ROOT過的手機 1,把代碼編寫好後,打包導出apk,到手機SD卡根目錄下。 2,手機連接eclipse,cmd: adb shell 3,切換root模式,輸入:su (如果root過就不會有錯誤) 4,設置System為讀寫許可權:mount –o remount rw /system (System默認為只讀,無法寫入,這一步很關鍵) 5,cd到sd卡跟目錄下,確認是否有我們拷貝到sd卡根目錄下的apk(一般都是 storage/sdcard0) shell@android:/ # cd storage/sdcard0 6,最關鍵的一步,我們要把apk拷貝到 /System/app中: 發現命令無效~那麼我們就用push把: 如果有錯誤:device not found,那麼手機下載一個Root Explorer把,找到apk,到System/app下,通過這個APP要更容易一些。 7,system/app 確定擁有我們的APK後,重啟手機把: 設置-應用程序管理,查看一下: 可以看到我們的APP已經無法卸載了,只能停用 這個時候,就算強制停止,或是關閉Service,重啟手機後照樣可以起來Service~! 系統級的APP,這樣一些第三方的管家軟體,就無法殺掉我們,除非自己把APP停用掉,或是強制停止(但是我的APP可以開機自啟動)。 【結論】這種方式適合調試來用,並不算是一種解決辦法,大家可以嘗試在正在運行的界面:強制關閉搜狐視頻的兩個進程,重啟手機,發現他又可以自啟動,但是如果換成我們的APP,強制停止,進程掛了,再重啟手機,無法自啟動了~

閱讀全文

與android防止被kill相關的資料

熱點內容
矩形密封圈壓縮量 瀏覽:591
電腦設置ntp時間同步伺服器地址 瀏覽:18
怎麼更有效招聘對日程序員 瀏覽:147
命令號角 瀏覽:275
格力雙轉子壓縮機 瀏覽:612
hp伺服器上的ip地址 瀏覽:560
c語言編程計算100以內的所有素數 瀏覽:624
命令輸入框 瀏覽:892
冰箱壓縮機發燙噪音 瀏覽:85
單片機棧溢出符號 瀏覽:330
命令與征服修改器怎麼用 瀏覽:485
什麼app比較費錢 瀏覽:832
為什麼同一個app的功能不一樣 瀏覽:232
小型工作室用什麼伺服器好 瀏覽:995
程序員的興趣 瀏覽:413
華為伺服器有什麼好 瀏覽:701
程序員和測試之間的關系 瀏覽:945
加密蚊帳什麼意思 瀏覽:151
javalistclear 瀏覽:607
哪個app上民宿多靠譜 瀏覽:828