国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > 建站經驗 > 正文

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

2019-11-02 14:33:26
字體:
來源:轉載
供稿:網友

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

 為什么是 foreground ? 默認啟動的 Service 是被標記為 background,當前運行的 Activity 一般被標記為 foreground,也就是說你給 Service 設置了 foreground 那么他就和正在運行的 Activity 類似優先級得到了一定的提高。當讓這并不能保證你得 Service 永遠不被殺掉,只是提高了他的優先級。 有一個方法可以給你更清晰的演示,進入 $SDK/tools 運行命令 復制代碼# adb shell dumpsys 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 如果他也完蛋了,你得系統也就掛了。 我是天王蓋地虎的分割線          
琪琪影院[www.aikan.tv/special/qiqiyingyuan/]
                       從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。 通過dumpsys activity命令能夠很明顯的看出其中差別。 復制代碼Running processes (most recent first):    App  # 3: adj=   2/1 ProcessRecord{30858c20 1877:com.android.email/10014} (started-services)    PERS # 2: adj=-100/0 ProcessRecord{308fb390 1713:system/1000} (fixed)    App  # 1: adj=   0/0 ProcessRecord{30908198 1794:android.process.acore/10005} (top-activity)    PERS # 0: adj= -12/0 ProcessRecord{3090d488 1789:xiao.xiong.test/10026} (fixed)復制代碼而且adj=-12時,這個進程通過ddms手動stop后會立即啟動 我是天王蓋地虎的分割線                                  方法對于一個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    4設置后的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中的進程是托管的,當
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 靖安县| 吐鲁番市| 松溪县| 新余市| 浦东新区| 肥城市| 连州市| 宁化县| 冕宁县| 乳山市| 含山县| 吉木萨尔县| 孟津县| 浦东新区| 商都县| 赤峰市| 南江县| 高州市| 丹巴县| 新丰县| 灵璧县| 腾冲县| 台前县| 万源市| 桃园县| 砀山县| 浦江县| 黄平县| 牟定县| 垫江县| 扎兰屯市| 曲水县| 当涂县| 郎溪县| 固镇县| 新巴尔虎左旗| 南安市| 板桥市| 静海县| 绿春县| 理塘县|