1. 程式人生 > >Android後臺保活4.0~8.0系統(一)

Android後臺保活4.0~8.0系統(一)

一:前言
在談保活之前,我們應該知道隨著Android系統的不斷髮展,系統管控越來越嚴格,後臺保活將是一個偽命題了,後臺保活主要是和推送相關,隨著技術的發展,泰爾終端實驗室也制定了統一的推送標準,我想在後面Android會像Iphone一樣,使用統一系統服務進行推送

二:關於Setting模組中關於保活的重要概念
1)開發者選項–不保留活動,即使用者離開後清除活動
當一個activity啟動的時候,他會關聯一個棧,同時棧也有自己的親和性的;大家可以搜尋launch moder瞭解下大致資訊;
這裡的不保留活動的意思距離說明是從activity A跳轉到activity B,則activity A被銷燬,如果此時點選back鍵,activity A會被重建

在7.0原始碼的Settings原始碼目錄裡面,如果你想通過“不保留活動”關鍵字去搜索對應程式碼是搜尋不到的,關鍵程式碼如下

res/xml/development_prefs.xml

        <SwitchPreference
            android:key="immediately_destroy_activities"
            android:title="@string/immediately_destroy_activities"
            android:summary="@string/immediately_destroy_activities_summary"
/>

相關類的位置 src/com/android/settings/DevelopmentSettings.java
選中開啟“不保留活動”選項執行的程式碼如下

    private void writeImmediatelyDestroyActivitiesOptions() {
        try {
            ActivityManagerNative.getDefault().setAlwaysFinish(
                    mImmediatelyDestroyActivities.isChecked());
        } catch
(RemoteException ex) { } }

檢視原始碼得知,setAlwaysFinish如下

    public void setAlwaysFinish(boolean enabled) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(enabled ? 1 : 0);
        mRemote.transact(SET_ALWAYS_FINISH_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

可以看出這個功能是通過往Settings.Global.ALWAYS_FINISH_ACTIVITIES寫入資料實現的;

在開啟設定這個app的時候,通過讀取相關的值來設定開關狀態

    private void updateImmediatelyDestroyActivitiesOptions() {
        updateSwitchPreference(mImmediatelyDestroyActivities, Settings.Global.getInt(
                getActivity().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0);
    }

其中ALWAYS_FINISH_ACTIVITIES為\frameworks\base\core\java\android\provider\Settings.java

         /**
         * If not 0, the activity manager will aggressively finish activities and
         * processes as soon as they are no longer needed.  If 0, the normal
         * extended lifetime is used.
         */
        public static final String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";

總結:當用戶勾選了“不保留活動”這個選項,則會將ALWAYS_FINISH_ACTIVITIES 設定為1,activity manager將在activity不在前臺的時候finish掉他

2)限制後臺程序
該功能可選的配置有:標準限制,無後臺程式,最多1個程式,最多2個程式…
xml配置檔案為:res/xml/development_prefs.xml

        <ListPreference
            android:key="app_process_limit"
            android:title="@string/app_process_limit_title"
            android:entries="@array/app_process_limit_entries"
            android:entryValues="@array/app_process_limit_values" />

選擇對應的條目之後,相關程式碼為:src/com/android/settings/DevelopmentSettings.java

    private void writeAppProcessLimitOptions(Object newValue) {
        try {
            int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
            ActivityManagerNative.getDefault().setProcessLimit(limit);
            updateAppProcessLimitOptions();
        } catch (RemoteException e) {
        }
    }

ActivityManagerNative.getDefault()實現如下:

    /**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

其中Singleton是一個模板類,通過get()方法返回IActivityManager;
那IActivityManager 的實現是誰尼,我們緊接著分析asInterface(b)

    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }

從這裡可以看出這裡才是真正的返回“in”,只有當in為null的時候,返回ActivityManagerProxy;

這裡的IActivityManager的實現者為:ActivityManagerService,最上面的ActivityManagerNative.getDefault().setProcessLimit(limit)其實是呼叫ActivityManagerService.java的setProcessLimit方法,我們來看一下詳細的方法

    @Override
    public void setProcessLimit(int max) {
        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                "setProcessLimit()");
        synchronized (this) {
            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
            mProcessLimitOverride = max;
        }
        trimApplications();
    }

這個方法的主要作用是殺死已經移除的程序,並動態調整oom adj for all processes;

綜述:限制後臺程序是強行獲取android.permission.SET_PROCESS_LIMIT許可權,殺死已經移除的程序並動態調整所有程序的oom adj

這裡我們並沒有解決標準顯示到底是限制多少個App,其實答案就在setProcessLimit方法中

 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;

這裡的ProcessList.MAX_CACHED_APPS的值為:

    // The maximum number of cached processes we will keep around before killing them.
    // NOTE: this constant is *only* a control to not let us go too crazy with
    // keeping around processes on devices with large amounts of RAM.  For devices that
    // are tighter on RAM, the out of memory killer is responsible for killing background
    // processes as RAM is needed, and we should *never* be relying on this limit to
    // kill them.  Also note that this limit only applies to cached background processes;
    // we have no limit on the number of service, visible, foreground, or other such
    // processes and the number of those processes does not count against the cached
    // process limit.
    static final int MAX_CACHED_APPS = 32;

也就是說標準顯示其實是允許保留32個後臺程序;