1. 程式人生 > >android程序保活

android程序保活

有些時候(國內通常是這樣)我們需要應用在 後臺存活,但是現在的很多手機room是在記憶體不足或者一定時間後銷燬程序的。

總結幾種android常用的保活手段。

系統出於體驗和效能上的考慮,app在退到後臺時系統並不會真正的kill掉這個程序,而是將其快取起來。開啟的應用越多,後臺快取的程序也越多。在系統記憶體不足的情況下,系統開始依據自身的一套程序回收機制來判斷要kill掉哪些程序,以騰出記憶體來供給需要的app, 這套殺程序回收記憶體的機制就叫 Low Memory Killer。

cat /sys/module/lowmemorykiller/parameters/minfree //檢視記憶體閾值

程序的優先順序通過程序的adj值來反映,它是linux核心分配給每個系統程序的一個值,程序回收機制根據這個值來決定是否進行回收。adj的值越小,程序的優先順序越高。

cat /proc/32393/oom_adj 檢視程序的adj值


一,提升程序優先順序

  1)Activity提權

監聽應用退入後臺以後就啟動一個透明的1px大小的activity

 2)Service提權

建立一個前臺服務用於提高app在按下home鍵之後的程序優先順序startForeground(ID,Notification):

API level < 18 :引數2 設定 new Notification(),圖示不會顯示。
API level >= 18:在需要提優先順序的service A啟動一個InnerService。兩個服務都startForeground,且繫結同樣的 ID。Stop 掉InnerService ,通知欄圖示被移除。

3)廣播拉活

在發生特定系統事件時,系統會發出廣播,通過在 AndroidManifest 中靜態註冊對應的廣播監聽器,即可在發生響應事件時拉活。
但是從android 7.0開始,對廣播進行了限制,而且在8.0更加嚴格

4)賬戶同步 拉活

手機系統設定裡會有“帳戶”一項功能,任何第三方APP都可以通過此功能將資料在一定時間內同步到伺服器中去。系統在將APP帳戶同步時,會將未啟動的APP程序拉活。(過程過於麻煩,而且不能控制重啟時間)

5)JobScheduler 拉活

JobScheduler允許在特定狀態與特定時間間隔週期執行任務。可以利用它的這個特點完成保活的功能,效果即開啟一個定時器,與普通定時器不同的是其排程由系統完成。
同樣在某些ROM可能並不能達到需要的效果(某米)

 public static void StartJob(Context context) {
        JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context
                .JOB_SCHEDULER_SERVICE);
//        setPersisted 在裝置重啟依然執行
        JobInfo.Builder builder = new JobInfo.Builder(10, new ComponentName(context
                .getPackageName(), MyJobService.class
                .getName())).setPersisted(true);
        //小於7.0
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            // 每隔1s 執行一次 job
            builder.setPeriodic(1_000);
        } else {
            //延遲執行任務
            builder.setMinimumLatency(1_000);
        }


        jobScheduler.schedule(builder.build());
    }


    private static final String TAG = "MyJobService";


    @Override
    public boolean onStartJob(JobParameters params) {
        Log.e(TAG, "開啟job");
        //如果7.0以上 輪訓
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            StartJob(this);
        }
        return false;
    }

不能保證適配所有機型

6)雙程序守護

這個是目前來說最靠譜的了,但是也不是一定可以(有些可以一鍵清理後臺程序的)。

class ServiceConnection implements android.content.ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //服務連線後回撥
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG,"主程序可能被幹掉了,拉活");
            //連線中斷後回撥
            startService(new Intent(RemoteService.this, LocalService.class));
            bindService(new Intent(RemoteService.this, LocalService.class), serviceConnection,
                    BIND_AUTO_CREATE);
        }
    }

另外還有native fork程序監聽主程序的,這個5.0之前還行,之後就廢了。