本文介绍Android四大组件之Service的调优以及进程保活,主要从以下几个方面来讲解:
service:直译为【服务】,但是在Android中通常总是称之为“后台服务”,其中“后台”一词是相对于前台来说的,那么什么是前台呢,一般来说是指Activity,用户可视界面。什么是后台呢?一般来说就是不可视界面,即Service。因此,从实际业务需求上来理解,Service的适用场景应该具备以下条件:
1.并不依赖于用户可视的UI界面
2.具有较长时间的运行特性
启动service的方式有两种,分别为startService()和bindService()
关闭service的方式也有两种,分别为stopService()和stopSelf()
1)startService
Intent startIntent = new Intent(this,MyService.class);
startService(startIntent); //启动服务
2)bindService
private MyService.DownloadBinder downloadBinder;
Intent intent = new Intent(ServiceActivity.this,MyService.class);
bindService(bindIntent,connection,BIND_AUTO_CREAT);
//绑定服务 BIND_AUTO_CREATE 表示在活动和服务进行绑定后自动创建服务。这会使得MyService中的onCreate方法得到执行
//但是onStartCommand()方法不会执行
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println(name+"ComponentName");
downloadBinder = (MyService.DownloadBinder) service;
downloadBinder.startDownload();
downloadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName name) {
//这个方法只有当service所在的进程crash或者被kill的时候,onServiceDisconnected才会被调用,
//如果要严重的话,请使用adbshell kill pid命令或者kill service来调用
System.out.println("解除绑定喽");
}
};
3)stopService
Intent stopIntent = new Intent(this,MyService.class);
stopService(stopIntent);
4) unbindService
unbindService(connection)
进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的独立单元。每个App系统默认分配一个进程。
线程:进程中的执行的一段程序片段。每个进程可以有多个线程,Android中的UI线程默认为主线程,其他的线程都为子线程。
需要注意的是:Service是运行在后台的一个组件,但是它也是默认运行在Android主线程上的,并且依赖于服务创建时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。
此外,也不要被服务的后台概念所迷惑,服务不会自动开启线程,所有Service中的代码都是默认运行在子线程上的,而且如果在service中不开启新线程,直接进行耗时操作,也会造成ANR,但是Service中造成ANR的时间会比Activit中长一点,为20s,activity为5s。
优先级依次降低
1)用户正在交互的Activity(onResume)
2)当某个Service绑定正在交互的Activity
3)被主动调用为前台Service(startForegroung())
4)组件正在执行生命周期的回调(onCreate()/onStart()/onDestory())
5)BroadCastReceiver正在执行onReceive()
1)我们的Activity正在处于onPause()(没有进入onStop)
2)绑定到前台Activity的Service
简单的startService()启动
对用户没有直接影响的进程-----Activity处于onStop的时候。
android:process =":xxx"
不含有任何的活动的组件。(Android设计的,为了第二次启动更快,采取的一个权衡)
(1)采取在锁屏时候,启动一个1像素的Activity,当用户解锁后将这个Activity结束掉(顺便同时把自己的核心服务再开启一次)。
背景:小米手机会在锁屏的时候,把所有程序全部杀死,为了省电。
(2)app运营厂商和手机厂商有合作关系--白名单
(3)双进程守护,防止单个进程被杀死,同时可以防止被第三方清理软件清理掉。一个进程被杀死,另外一个进程又被它启动。相互监听启动。 设想?假如两个都被杀死了怎么办?
通过分析源码,可以得出:系统杀进程是一个一个杀的。所以这种方式本质上就是和杀进程时间赛跑。
(4)JobScheduler
把任务加到系统调度队列中,当到达任务窗口期的时候就会执行,我们可以在这个任务里面启动我们的进程。这样可以做到奖金杀不死的程序。
(5)监听QQ,微信,系统应用,友盟,小米推送等等的广播,然后把自己启动了。
(6)利用账号同步唤醒机制唤醒我们的进程,AccountManager
(7)NDK来解决,Native进程来实现双进程守护
总结:随着Android系统的不断升级,其安全性和规范性也变得越来越高,所以想达到绝对的防杀死的功能是几乎不可能的,除非软件达到"微信"或者"QQ"这样的用户量,但是我们还是可以使用以上的这些方法,尽量提升程序的优先级。由此看来这是一场长期的手机开发者和手机Rom厂商之间的一场拉锯战。
Demo已上传:
单进程保活
双进程守护保活