没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
11页
前言 最近有在项目中用到高德的定位SDK,功能是每隔一定的时间获取一次用户的地理位置,采取的方案是在后台开启一个 Service,监听高德地图的位置变化。 该功能在用户手机屏幕亮时完美实现,但是当屏幕被关闭的时候,位置信息却无法被获取了,经过原因的排查,发现是由于在用户手机息屏后,后台的 Service 被系统清除,所以功能无法起作用,也就是所谓的进程被杀了。 杀进程,一方面是因为手机内存不足,另一方面其实是 Google 从用户的方面考虑,把一些常驻后台的程序通过一定的算法进行管理,将那些过度消耗系统资源的流氓软件杀除,保证手机的性能和续航。但是有的软件,像定位这类的必须要保持后台的运行,
资源详情
资源评论
资源推荐
Android 双进程守护的实现代码双进程守护的实现代码
前言前言
最近有在项目中用到高德的定位SDK,功能是每隔一定的时间获取一次用户的地理位置,采取的方案是在后台开启一个
Service,监听高德地图的位置变化。
该功能在用户手机屏幕亮时完美实现,但是当屏幕被关闭的时候,位置信息却无法被获取了,经过原因的排查,发现是由于在
用户手机息屏后,后台的 Service 被系统清除,所以功能无法起作用,也就是所谓的进程被杀了。
杀进程,一方面是因为手机内存不足,另一方面其实是 Google 从用户的方面考虑,把一些常驻后台的程序通过一定的算法进
行管理,将那些过度消耗系统资源的流氓软件杀除,保证手机的性能和续航。但是有的软件,像定位这类的必须要保持后台的
运行,如何才能避免被系统杀掉呢。其实避免被杀进程很难做到,除非是像微信、QQ、支付宝这类系统厂商认可的软件被官
方加入白名单可以避免被杀进程。那其他的小软件怎么办,我们可以另辟蹊径,无法避免被杀进程,那就让我们的软件在被杀
进程后,能自动重启。
我这里介绍一下双进程守护的方法,来实现进程被杀后的拉起。
双进程守护双进程守护
双进程守护的思想就是,两个进程共同运行,如果有其中一个进程被杀,那么另一个进程就会将被杀的进程重新拉起,相互保
护,在一定的意义上,维持进程的不断运行。
双进程守护的两个进程,一个进程用于我们所需的后台操作,且叫它本地进程,另一个进程只负责监听着本地进程的状态,在
本地进程被杀的时候拉起,于此同时本地进程也在监听着这个进程,准备在它被杀时拉起,我们将这个进程称为远端进程。
由于在 Android 中,两个进程之间无法直接交互,所以我们这里还要用到 AIDL (Android interface definition Language ),
进行两个进程间的交互。
代码实现代码实现
先来看一下demo代码结构,结构很简单,我这里创建了一个 Activity 作为界面,以及两个 Service ,一个是后台操作的 本地
Service,另一个是守护进程的 远端Service,还有一个 AIDL文件用作进程间交互用。
项目结构
Activity 的定义很简单,就几个按钮,控制 Service 的状态,我这边定义了三个按钮,一个是开启后台服务,另外两个分别是
关闭本地Service和远端的Service。
/**
* @author chaochaowu
*/
public class GuardActivity extends AppCompatActivity {
@BindView(R.id.button)
Button button;
@BindView(R.id.button2)
Button button2;
@BindView(R.id.button3)
Button button3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_guard);
ButterKnife.bind(this);
}
@OnClick({R.id.button, R.id.button2, R.id.button3})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.button:
startService(new Intent(this, LocalService.class));
break;
case R.id.button2:
stopService(new Intent(this, LocalService.class));
break;
case R.id.button3:
stopService(new Intent(this, RemoteService.class));
break;
default:
break;
}
}
}
可以看一下界面。
主界面
AIDL文件可以根据业务需要添加接口。
/**
* @author chaochaowu
*/
interface IMyAidlInterface {
String getServiceName();
}
重点是在两个 Service 上。
在定义Service时,需要在 AndroidManifest 中声明一下 远端Service 的 process 属性,保证 本地Service 和 远端Service 两者
跑在不同的进程上,如果跑在同一个进程上,该进程被杀,那就什么都没了,就没有了双进程守护的说法了。
<service
android:name=".guard.LocalService"
android:enabled="true"
android:exported="true" />
<service
android:name=".guard.RemoteService"
android:enabled="true"
android:exported="true"
android:process=":RemoteProcess"/>
先来看 LocalService 的代码,重点关注 onStartCommand 方法 和 ServiceConnection 中重写的方法。onStartCommand 方法
是在 Service 启动后被调用,在 LocalService 被启动后,我们将 RemoteService 进行了启动,并将 LocalService 和
RemoteService 两者绑定了起来(因为远端Service 对于用户来说是不可见的,相对于我们实际工作的进程也是独立的,它的
作用仅仅是守护线程,所以说 RemoteService 仅与 LocalService 有关系,应该只能由 LocalService 将它启动)。
启动并绑定之后,我们需要重写 ServiceConnection 中的方法,监听两者之间的绑定关系,关键的是对两者绑定关系断开时的
监听。
当其中一个进程被杀掉时,两者的绑定关系就会被断开,触发方法 onServiceDisconnected ,所以,我们要在断开时,进行进
程拉起的操作,重写 onServiceDisconnected 方法,在方法中将另外一个 Service 重新启动,并将两者重新绑定。
/**
* @author chaochaowu
剩余10页未读,继续阅读
weixin_38626080
- 粉丝: 8
- 资源: 973
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0