美文网首页
android进程保活

android进程保活

作者: 刘佳阔 | 来源:发表于2018-04-19 16:15 被阅读0次

目前只是记录,没实际意义

1.微信的做法

  1. 微信拆分了三个进程.
    a. push主要用于网络交互,没有UI,进程的内存增加少.工作稳定.
    b. worker就是用户看到的主要UI进程.
    c. tools主要包含gallery和webview.老版webView存在内存泄漏,并且gallery(应该是朋友圈)存在打了略缩图导致内存变大,在进入后台会结束这个进程.
  2. 进程保活实施:及时拉起
    a.push进程监听有AlarmReceiver, ConnectReceiver,BootReceiver种广播,这些receiver 都可以在push被杀后,重新拉起.
    b.worker进程会通过push进程发送广播拉起.
    c.push和worker通信使用Broadcast和AIDL
  3. 进程保活原理:进程优先级
* 前台进程(Foreground process)。它表明用户正在与该进程进行交互操作,android系统依据下面的条件来将一个进程标记为前台进程:

该进程持有一个用户正在与其交互的Activity(也就是这个activity的生命周期方法走到了onResume()方法)。
该进程持有一个Service,并且这个Service与一个用户正在交互中的Activity进行绑定。
该进程持有一个前台运行模式的Service(也就是这个Service调用了startForegroud()方法)。
该进程持有一个正在执行生命周期方法(onCreate()、onStart()、onDestroy()等)的Service。
该进程持有一个正在执行onReceive()方法的BroadcastReceiver。
一般情况下,不会有太多的前台进程。杀死前台进程是操作系统最后无可奈何的做法。当内存严重不足的时候,前台进程一样会被杀死。

* 可见进程(Visible process)。它表明虽然该进程没有持有任何前台组件,但是它还是能够影响到用户看得到的界面。
android系统依据下面的条件将一个进程标记为可见进程:

该进程持有一个非前台Activity,但这个Activity依然能被用户看到(也就是这个Activity调用了onPause()方法)。例如,
当一个activity启动了一个对话框,这个activity就被对话框挡在后面。该进程持有一个与可见(或者前台)Activity绑定的Service。

*服务进程(Service process)。除了符合前台进程和可见进程条件的Service,其它的Service都会被归类为服务进程。

* 后台进程(Background process)。持有不可见Activity(调用了onStop()方法)的进程即为后台进程。通常情况下都会有很多后台进程,
当内存不足的时候,在所有的后台进程里面,会按照LRU(最近使用)规则,优先回收最长时间没有使用过的进程。

* 空进程(Empty process)。不持有任何活动组件的进程。保持这种进程只有一个目的,就是为了缓存,
以便下一次启动该进程中的组件时能够更快响应。当资源紧张的时候,系统会平衡进程缓存和底层的内核缓存情况进行回收

办法.Android 的前台service机制.提高进程优先级
对于 API level < 18 :调用startForeground(ID, new Notification()),发送空的Notification ,图标则不会显示。对于 API level >= 18:在需要提优先级的service A启动一个InnerService,两个服务同时startForeground,且绑定同样的 ID。Stop 掉InnerService ,这样通知栏图标即被移除。
两个service代码如下

public class GrayService extends Service {
    private final static int GRAY_SERVICE_ID = 1001;
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (Build.VERSION.SDK_INT < 18) {
            startForeground(GRAY_SERVICE_ID, new Notification());//API < 18 ,此方法能有效隐藏Notification上的图标
        } else {
            Intent innerIntent = new Intent(this, GrayInnerService.class);
            startService(innerIntent);
            startForeground(GRAY_SERVICE_ID, new Notification());
        }
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 给 API >= 18 的平台上用的灰色保活手段
     */
    public static class GrayInnerService extends Service {

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(GRAY_SERVICE_ID, new Notification());
            stopForeground(true);
            stopSelf();
            return super.onStartCommand(intent, flags, startId);
        }

    }
}

2.1像素activity技术.

某些启用后台服务场景中,为了防止我们的应用被第三方应用或系统管理工具在锁屏后为省电而被杀死,我们可以通过启动一像素大小的界面来提升进程等级,让进程等级从后台进程提升到前台进程。
1.1像素activity

public class OnePixelActivity extends Activity {  
  
    private static final String TAG = "MyLog";  
  
    public static OnePixelActivity instance = null;  
  
    @Override  
    protected void onCreate(@Nullable Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_one_pixel);  
        Window window = getWindow();  
        // 放在左上角  
        window.setGravity(Gravity.START | Gravity.TOP);  
        WindowManager.LayoutParams layoutParams = window.getAttributes();  
        // 宽高为1px  
        layoutParams.width = 1;  
        layoutParams.height = 1;  
        // 起始坐标  
        layoutParams.x = 0;  
        layoutParams.y = 0;  
        window.setAttributes(layoutParams);  
        instance = this;  
        Log.d(TAG, "activity onCreate");  
    }  
  
    @Override  
    protected void onDestroy() {  
        instance = null;  
        Log.d(TAG, "activity onDestroy");  
        super.onDestroy();  
    }  
}

2.编写广播接收器监听锁屏和解锁action:锁屏时开启activity.亮屏时关闭.

public class ScreenBroadcastReceiver extends BroadcastReceiver {  
  
    private static final String TAG = "MyLog";  
  
    @Override  
    public void onReceive(Context context, Intent intent) {  
        String action = intent.getAction();  
        switch (action) {  
            case Intent.ACTION_SCREEN_ON: { //  
                Log.d(TAG, "screen_on");  
                // 关闭一像素Activity  
                if (OnePixelActivity.instance != null) {  
                    OnePixelActivity.instance.finish();  
                }  
                break;  
            }  
            case Intent.ACTION_SCREEN_OFF: {  
                Log.d(TAG, "screen_off");  
                // 开启一像素Activity  
                Intent activityIntent = new Intent(context, OnePixelActivity.class);  
                activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
                context.startActivity(activityIntent);  
                break;  
            }  
            default:  
                break;  
        }  
    }  
}
值得注意的是Intent.ACTION_SCREEN_ON与Intent.ACTION_SCREEN_OFF只有通过Context.registerReceiver方法注册的广播接收器才能监听到

3.服务里开启广播监听

public class WorkService extends Service {  
  
    private static final String TAG = "MyLog";  
  
    private ScreenBroadcastReceiver receiver;  
  
    @Nullable  
    @Override  
    public IBinder onBind(Intent intent) {  
        return null;  
    }  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "service onCreate");  
        receiver = new ScreenBroadcastReceiver();  
        IntentFilter intentFilter = new IntentFilter();  
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);  
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);  
        registerReceiver(receiver, intentFilter);  
    }  
  
    @Override  
    public void onDestroy() {  
        Log.d(TAG, "service onDestroy");  
        unregisterReceiver(receiver);  
        super.onDestroy();  
    }  
}

相关文章

网友评论

      本文标题:android进程保活

      本文链接:https://www.haomeiwen.com/subject/ljzikftx.html