美文网首页
Android 使用MarsDaemon进程常驻

Android 使用MarsDaemon进程常驻

作者: 胡二囧 | 来源:发表于2017-09-25 17:17 被阅读0次

    在特定的业务场景中,我们可能会需要app在后台做一些事情,比如上传数据之类的操作,并且希望这种操作及时在程序退出之后依然可以继续进行。因此也就理所当然的想到了使用Service进行处理。但是,在特定条件(app进入后台+设备内存不足+进程占用的内存足够大)的情况下,Service会非常容易在几分钟内被系统干掉,因此提高Service的存活率至关重要。

    一种无效的做法

        public void onDestroy() {
            Log.e(TAG, "onDestory");
            Intent intent = new Intent(this, Service.class);
            startService(intent);
            super.onDestroy();
        }
    

    此方法企图利用Service是生命周期去调用其本身,事实证明这种方法是无效的,在进程被杀死时,Service根本不会执行onDestroy就被直接清出内存了,因此靠自身的力量提高存活率的方式也就不可行了。

    Marsdaemon

    Github获取项目源码

    导入项目之后


    项目目录

    之后不要忘记导入module

    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        testCompile 'junit:junit:4.12'
        compile project(':LibMarsdaemon')
    }
    

    使用Marsdaemon

    在manifest中声明2个进程分别包含一个Service和一个Receiver

    此处将process1作为主要进程,process2作为守护进程。MainService中执行主要的业务逻辑,Receiver1、GuardService、Receiver2都是额外创建的,里面不要做任何事情,都是空实现就好。

    <!--守护进程-->
    <service
        android:name=".ble.MainService"
        android:enabled="true"
        android:exported="true"
        android:process=":process1" />
    <receiver
        android:name=".guard.Receiver1"
        android:process=":process1" />
    <service
        android:name=".guard.GuardService"
        android:process=":process2" />
    <receiver
        android:name=".guard.Receiver2"
        android:process=":process2" />
    

    处理Application

    由于我们的Application一般都会集成其他的Application,因此需要在attachBaseContext中初始化DaemonClient,然后调用onAttachBaseContext即可实现

    public class MyApplication extends XXXApplication {
        private DaemonClient daemonClient;
    
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            daemonClient = new DaemonClient(getDaemonConfigurations());
            daemonClient.onAttachBaseContext(base);
        }
        
        private DaemonConfigurations getDaemonConfigurations() {
            DaemonConfigurations.DaemonConfiguration configuration1 = 
            new DaemonConfigurations.DaemonConfiguration(
                    "com.hemaapp.znsh:process1",
                    MainService.class.getCanonicalName(),
                    Receiver1.class.getCanonicalName());
    
            DaemonConfigurations.DaemonConfiguration configuration2 = 
            new DaemonConfigurations.DaemonConfiguration(
                    "com.hemaapp.znsh:process2",
                    GuardService.class.getCanonicalName(),
                    Receiver2.class.getCanonicalName());
    
            DaemonConfigurations.DaemonListener listener = new MyDaemonListener();
            /*return new DaemonConfigurations(configuration1, configuration2);listener可以是null*/
            return new DaemonConfigurations(configuration1, configuration2, listener);
        }
        private class MyDaemonListener implements DaemonConfigurations.DaemonListener {
            @Override
            public void onPersistentStart(Context context) {
            }
    
            @Override
            public void onDaemonAssistantStart(Context context) {
            }
    
            @Override
            public void onWatchDaemonDaed() {
            }
        }
    }
    

    处理其他Class

    public class GuardService extends Service {
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return Service.START_NOT_STICKY;
        }
    }
    
    public class Receiver1 extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
        }
    }
    
    public class Receiver2 extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
    
        }
    }
    

    使用

    在Android4.4中

    • 手动Kill进程时,可以明显的在LogCat中看到Service被重新启动了,提高的Service的存活率。

    在Android5+中

    • 手动Kill进程时,Service不会被重新启动,Application依旧被彻底杀死了。
    • 小米2+Android5.0,长时间后台运行测试中,可以连续半小时以上不间断发送网络请求,效果明显。
    • 其他主流手机,由于大多配置了2G以上的内存,因此暂时没有看到Service被清理的现象发生。

    后记

    使用Marsdaemon提高Service存活率的方式虽然有一定效果,但是在Android5.0之后的版本中,并不可靠,并且还有如下几个缺陷。

    • 即使Service存活,Application中的信息不一定全部存在,这就会导致发送网络请求失败的情况发生,做了无用功。
    • 营造了一个恶劣的运行环境,这种方式也是Android所不提倡的。

    因此,Marsdaemon不应是大家频繁使用的功能,特殊情况下可以应急即可。

    相关文章

      网友评论

          本文标题:Android 使用MarsDaemon进程常驻

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