简单跨进程使用EventBus

·  阅读 2945

一、结构

说明:

  1. 主进程有一个Service,负责维护监听器列表,以及监听相关事件,并发送给子进程
  2. 子进程需要绑定主进程的Service,并注册监听
  3. 主进程和子进程内的事件通过EventBus发送,需要跨进程的通过Binder转发

二、AIDL接口

工程结构:

定义AIDL接口:
IEventInterface.aidl:
// IEventInterface.aidl
package com.example.autolog.aidl;
import com.example.autolog.aidl.IRemoteCallback;
// Declare any non-default types here with import statements
import com.example.autolog.aidl.Msg;
interface IEventInterface {
    //子进程向主进程注册事件回调
    void registerCallback(IRemoteCallback callback);
	//子进程解注册
    void unregisterCallback(IRemoteCallback callback);
	//子进程向主进程通知事件
    void notify(in Msg msg);
}
复制代码
IRemoteCallback.aidl:
// IRemoteCallback.aidl
package com.example.autolog.aidl;

// Declare any non-default types here with import statements
import com.example.autolog.aidl.Msg;

interface IRemoteCallback {
    //子进程实现的事件回调
    void notifyEvent(in Msg msg);
}
复制代码
Msg.aidl:
// Msg.aidl
package com.example.autolog.aidl;
//消息类型
parcelable Msg;
复制代码

三、本地客户端

Msg.java:
package com.example.autolog.aidl;

import android.os.Parcel;
import android.os.Parcelable;
//消息实体类,需要实现Parcelable接口,跨进程时需要进行序列化
public class Msg implements Parcelable {
    public int code;
    public String message;

    public Msg(int code, String msg) {
        this.code = code;
        this.message = msg;
    }

    public Msg(Parcel in) {
        this.code = in.readInt();
        this.message = in.readString();
    }

    public final static Creator<Msg> CREATOR = new Creator<Msg>() {
        @Override
        public Msg createFromParcel(Parcel in) {
            return new Msg(in);
        }

        @Override
        public Msg[] newArray(int size) {
            return new Msg[size];
        }
    };

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(code);
        dest.writeString(message);
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
复制代码
LocalService.java:主进程的Service,其他进程需要绑定该Service
package com.example.autolog.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

import de.greenrobot.event.EventBus;
import de.greenrobot.event.Subscribe;

public class LocalService extends Service {
    //监听列表,使用RemoteCallbackList可以进行监听对象的移除
    final RemoteCallbackList<IRemoteCallback> lis = new RemoteCallbackList<>();
    Binder mBinder = new IEventInterface.Stub() {
        @Override
        public void registerCallback(IRemoteCallback callback) throws RemoteException {
            Log.v("aidl-service", "localservice registercallback:" + callback + callback.asBinder());
            lis.register(callback);
        }

        @Override
        public void unregisterCallback(IRemoteCallback callback) throws RemoteException {
            Log.v("aidl-service", "localservice unregistercallback " + callback + callback.asBinder());
            lis.unregister(callback);
        }

        @Override
        public void notify(Msg msg) throws RemoteException {
            Log.v("aidl-service", "localservice notify code:" + msg.code + " message:" + msg.message);
            //子进程发送事件后,用EventBus分发
            EventBus.getDefault().post(msg);
        }
    };

	//监听EventBus发送的字符串事件,并调用子进程的监听器
    @Subscribe
    public void handle(String message) {
        Log.v("aidl-service", "localservice handle:" + message);
        synchronized (lis) {
            int n = lis.beginBroadcast();
            try {
                for (int i = 0; i < n; i++) {
                    lis.getBroadcastItem(i).notifyEvent(new Msg(0, message));
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            lis.finishBroadcast();
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}
复制代码
MainActivity.java:主页面,此处用来启动LocalService和RemoteService
package com.example.autolog;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.example.autolog.aidl.Msg;
import com.example.autolog.aidl.RemoteService;
import com.example.autolog.aidl.LocalService;

import de.greenrobot.event.EventBus;
import de.greenrobot.event.Subscribe;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

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

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

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(3000);
                        //发送事件,由LocalService处理,并通知给子进程
                        EventBus.getDefault().post("wahaha, i'am mainactivity:" + System.currentTimeMillis());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        EventBus.getDefault().register(this);
    }

    @Subscribe
    public void process(Msg msg){
        //子进程事件发送到LocalService后,处理EventBus发送的事件
        Log.v("aidl-service", "main activity preocess code:"+msg.code+" msg:"+msg.message);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}
复制代码

四、子进程

RemoteService:子进程,用来绑定主进程,并注册监听

package com.example.autolog.aidl;

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

import androidx.annotation.Nullable;

import com.example.autolog.LocalService;
import com.example.autolog.aidl.IEventInterface;
import com.example.autolog.aidl.IRemoteCallback;
import com.example.autolog.aidl.Msg;

import de.greenrobot.event.EventBus;

public class RemoteService extends Service {
    IEventInterface iEventInterface;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.v("aidl-service", "remoteservice oncreate " + getPackageName());
        Intent it = new Intent(this, LocalService.class);
        //绑定主进程的服务
        boolean r = bindService(it, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.v("aidl-service", "remoteservice onserviceconnected");
                iEventInterface = IEventInterface.Stub.asInterface(service);
                try {
                    //注册监听
                    iEventInterface.registerCallback(new IRemoteCallback.Stub() {
                        @Override
                        public void notifyEvent(Msg msg) throws RemoteException {
                            Log.v("aidl-service", "remoteservice notifyevent code:" + msg.code + " message:" + msg.message);
                            EventBus.getDefault().post(msg);
                        }
                    });
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            while (true) {
                                try {
                                    Thread.sleep(2000);
                                    //向主进程发送事件
                                    iEventInterface.notify(new Msg(1, "hello i'am remoteservice:" + System.currentTimeMillis()));
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }).start();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        }, BIND_AUTO_CREATE);
        Log.e("aidl-service", "remoteservice bind localservice " + r);
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
复制代码

在AndroidManifest.xml中配置service

<service android:name=".LocalService" >
   <intent-filter>
         <action android:name="localservice"/>
   </intent-filter>
</service>

<service
    android:name=".aidl.RemoteService"
    android:process=":remote" />
复制代码

通过以上的代码,可以实现使用EventBus在主进程和子进程之间通信。

五、多module

将主进程的service和子进程的service放到不同的module中:

base:基础module,包含了aidl文件和Msg实体类,以及LocalService

child:子进程,包含RemoteService,并在AndroidManifest.xml配置service的进程,需要在build.gradle中配置对base的依赖

app:主module,包含MainActivity,需要在build.gradle中配置对base和child的依赖

六、多APP通信

将AIDL文件和实体类拷贝到main目录下,保证包名和路径正确,即可实现app之间的通信。

在第二个APP中,使用显式的intent来绑定第一个APP中的LocalService,使用LocalService设置的action。

分类:
Android
标签:
分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改