这期内容当中小编将会给大家带来有关怎么在Android中实现双进程守护,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
双进程守护
双进程守护的思想就是,两个进程共同运行,如果有其中一个进程被杀,那么另一个进程就会将被杀的进程重新拉起,相互保护,在一定的意义上,维持进程的不断运行。
双进程守护的两个进程,一个进程用于我们所需的后台操作,且叫它本地进程,另一个进程只负责监听着本地进程的状态,在本地进程被杀的时候拉起,于此同时本地进程也在监听着这个进程,准备在它被杀时拉起,我们将这个进程称为远端进程。
由于在 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
*/
public class LocalService extends Service {
private MyBinder mBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
Log.i("LocalService", "connected with " + iMyAidlInterface.getServiceName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(LocalService.this,"链接断开,重新启动 RemoteService",Toast.LENGTH_LONG).show();
startService(new Intent(LocalService.this,RemoteService.class));
bindService(new Intent(LocalService.this,RemoteService.class),connection, Context.BIND_IMPORTANT);
}
};
public LocalService() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"LocalService 启动",Toast.LENGTH_LONG).show();
startService(new Intent(LocalService.this,RemoteService.class));
bindService(new Intent(this,RemoteService.class),connection, Context.BIND_IMPORTANT);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
mBinder = new MyBinder();
return mBinder;
}
private class MyBinder extends IMyAidlInterface.Stub{
@Override
public String getServiceName() throws RemoteException {
return LocalService.class.getName();
}
}
}
在另外一个 RemoteService 中也一样,在与 LocalService 断开链接的时候,由于监听到绑定的断开,说明 RemoteService 还存活着,LocalService 被杀进程,所以要将 LocalService 进行拉起,并重新绑定。方法写在 onServiceDisconnected 中。
/**
* @author chaochaowu
*/
public class RemoteService extends Service {
private MyBinder mBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
Log.i("RemoteService", "connected with " + iMyAidlInterface.getServiceName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(RemoteService.this,"链接断开,重新启动 LocalService",Toast.LENGTH_LONG).show();
startService(new Intent(RemoteService.this,LocalService.class));
bindService(new Intent(RemoteService.this,LocalService.class),connection, Context.BIND_IMPORTANT);
}
};
public RemoteService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"RemoteService 启动",Toast.LENGTH_LONG).show();
bindService(new Intent(this,LocalService.class),connection,Context.BIND_IMPORTANT);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
mBinder = new MyBinder();
return mBinder;
}
private class MyBinder extends IMyAidlInterface.Stub{
@Override
public String getServiceName() throws RemoteException {
return RemoteService.class.getName();
}
}
}
Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。
上述就是小编为大家分享的怎么在Android中实现双进程守护了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。