Android 使用MarsDaemon进程常驻

2017-09-25  本文已影响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中

在Android5+中

后记

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

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

上一篇下一篇

猜你喜欢

热点阅读