这期内容当中小编将会给大家带来有关怎么在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中实现双进程守护了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。