关闭

进程保活-双进程守护的正确姿势

标签: android
118人阅读 评论(0) 收藏 举报
分类:

做车机的开发免不了在后台开很多服务,做车机的APP跟做普通的手机APP区别在于做车机要用到很多的进程间的通信交互等,一个应用死了,可能导致整个机器都运转不正常了,不会进程间的通信怎么可以,撸起来!

双进程守护,肯定得用到多进程,一个应用可以有多个进程的,如何实现多进程呢,service或者activity等都有一个属性android:process,只要设置起名称就可指定该组件运行在该进程中。在这里我们就指定了RemoteService运行在包名.remote这个进程中。

   <service
            android:name=".LocalService"
            android:enabled="true"
            android:exported="true" />
        <service
            android:name=".RemoteService"
            android:enabled="true"
            android:exported="true"
            android:process=".remote"></service>

首先我们在MainActivity中启动两个Activity,

startService(new Intent(this, LocalService.class));
startService(new Intent(this, RemoteService.class));

为什么加双进程守护呢,A死掉B拉A起来,B死掉A拉B起来,那么A和B怎么知道对方有没有死呢?当然用AIDL,就是进程间的通信实现的一种方式。

首先在main下面写一个aidl文件
这里写图片描述

然后在build 下reBuild一下工程,就可生成aidl对应的java文件
这里写图片描述

下面开始正式的代码编写
两个Service的代码基本相同
首先在LocalService中绑定RemoteService

 class MyBinder extends MyAidlInterface.Stub {

        @Override
        public String getServiceName() throws RemoteException {
            return LocalService.class.getSimpleName();
        }
    }

当绑定关系断掉,也就是RemoteService死掉时,在LocalService中把它启动起来并且重新建立绑定关系:

class MyConn implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("LocalService", "onServiceConnected: " );
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("LocalService", "onServiceDisconnected: " );
            LocalService.this.startService(new Intent(LocalService.this, RemoteService.class));
            LocalService.this.bindService(new Intent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);
        }
    }

核心代码就是上面两段,在RemoteService中的操作基本与之相同。
整体代码如下:

LocalService的代码如下:
package keepalive.com.xn.keepalive;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class LocalService extends Service {
    MyBinder binder;
    MyConn conn;

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        binder = new MyBinder();
        if (conn == null) {
        conn = new MyConn();
        }

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        this.bindService(new Intent(this, RemoteService.class), conn, Context.BIND_IMPORTANT);
        return super.onStartCommand(intent, flags, startId);
    }

    class MyBinder extends MyAidlInterface.Stub {

        @Override
        public String getServiceName() throws RemoteException {
            return LocalService.class.getSimpleName();
        }
    }

    /**
     * 连接时需要用到此类
     */
    class MyConn implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("LocalService", "onServiceConnected: " );
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("LocalService", "onServiceDisconnected: " );
            LocalService.this.startService(new Intent(LocalService.this, RemoteService.class));
            LocalService.this.bindService(new Intent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);
        }
    }
}
RemoteService的代码如下:
package keepalive.com.xn.keepalive;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class RemoteService extends Service {
    MyBinder binder;
    MyConn conn;

    public RemoteService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        binder = new MyBinder();
        if (conn == null) {
            conn = new MyConn();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        this.bindService(new Intent(this, LocalService.class), conn, Context.BIND_IMPORTANT);
        return super.onStartCommand(intent, flags, startId);
    }

    class MyBinder extends MyAidlInterface.Stub {

        @Override
        public String getServiceName() throws RemoteException {
            return RemoteService.class.getSimpleName();
        }
    }

    /**
     * 连接时需要用到此类
     */
    class MyConn implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(RemoteService.this.toString(), "onServiceConnected: ");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(RemoteService.this.toString(), "onServiceDisconnected: ");
            RemoteService.this.startService(new Intent(RemoteService.this, LocalService.class));
            RemoteService.this.bindService(new Intent(RemoteService.this, LocalService.class), conn, Context.BIND_IMPORTANT);
        }
    }
}

思路和代码都是非常简单的,当然还有其他的保活方式,以后再说咯。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:7942次
    • 积分:417
    • 等级:
    • 排名:千里之外
    • 原创:35篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条