如今多進程傳遞數據使用愈來愈普遍了,在 Android 中進程間通訊提供了 文件
、AIDL
、Binder
、Messenger
、ContentProvider
、Socket
、MemoryFile
等,實際開發中使用最多的應該是 AIDL ,可是 AIDL 須要編寫 aidl 文件,若是使用 AIDL 僅僅是爲了傳遞數據, 那麼 YKProBus 是你不錯的選擇。java
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
複製代碼
dependencies {
implementation 'com.github.yangkun19921001:YKProBus:1.0.1'
}
複製代碼
EventManager.getInstance().bindApplication(Context context,String proName);
複製代碼
EventManager.getInstance().sendMessage(int messageTag,Bundle bundle);
複製代碼
<service
android:name="com.devyk.component_eventbus.proevent.service.MessengerService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.devyk.component_eventbus.service"></action>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
複製代碼
6.1 在須要接收消息的類中實現 IMessageHandler 並實例化一個 Handler 用於接收發送進程發來的消息android
public class MainActivity extends Activity implements IMessageHandler{
...
/** * 接收其它進程發送過來的消息 * * @return */
@Override
public Handler getHandler() {
return new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0x001:
...
break;
}
}
};
}
...
}
複製代碼
6.2 註冊當前類須要接收消息git
EventManager.getInstance().registerMessager(int messageTag, Object obj);
複製代碼
Messenger 內部其實也是依賴 aidl 實現的進程間通訊。github
@Override
public IBinder onBind(Intent intent) {
return mServiceMessenger.getServiceMessenger().getBinder();
}
複製代碼
getBinder() 跟進去app
public IBinder getBinder() {
return mTarget.asBinder();
}
複製代碼
mTarget 從何而來,從源碼找找框架
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
複製代碼
這裏是咱們實例化 服務端 Messenger 傳入的 Handler targetmaven
/** * 初始化服務端 Messenger */
public MessengerManager() {
if (null == mServiceMessenger)
mServiceMessenger = new Messenger(mMessengerServiceHandler);
}
複製代碼
那麼咱們在點擊 getIMessenger() 在看看內部實現ide
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
複製代碼
繼續點擊 MessengerImple函數
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
複製代碼
這個是一個內部實現的類,能夠看到繼承的是 IMessenger.Stub 而後實現 send (Message msg) 函數,而後經過 mTarget.sendMessage(msg) 發送消息,最後在咱們傳入進去的 mMessengerServiceHandler 的 handleMessage (Message) 接收發來的消息。源碼分析
既然這裏內部幫咱們寫了 aidl 文件 ,而且也繼承了 IMessenger.Stub 咱們今天就要看到 aidl 才死心 , 好吧咱們來找找 IMessenger aidl 文件。
能夠看到是在 framework/base/core/java/android/os 路徑中,咱們點擊在來看下文件中怎麼寫的
內部就一個 send 函數,看到這,你們應該都明白了,Messenger 其實也沒什麼大不了,就是系統內部幫咱們寫了 aidl 而且也實現了 aidl ,最後又幫咱們作了一個 Handler 線程間通訊,因此服務端收到了客服端發來的消息。
客服端須要在 bindServicer onServiceConnected 回調中拿到 servicer, 平時咱們本身寫 應該是這麼拿到 Ibinder 對象吧
IMessenger mServiceMessenger = IMessenger.Stub.asInterface(service);
複製代碼
可是咱們實際客服端是這樣拿到服務端的 Messenger
/** * 服務端消息是否鏈接成功 */
private class EventServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
isBindApplication = true;
// 獲得服務信使對象
mServiceMessenger = new Messenger(service);
//將本地信使告訴服務端
registerMessenger();
String proName = ProcessUtils.getProName(mApplicationContext);
Log.d(TAG, " EventServiceConnection " + proName);
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBindApplication = false;
}
}
複製代碼
// 獲得服務信使對象
mServiceMessenger = new Messenger(service);
複製代碼
跟進去
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
複製代碼
這不就是咱們剛剛說的本身實現的那種寫法吧,到這裏咱們都懂了吧,咱們平時寫的 aidl android 中已經幫咱們寫了,想當於在 aidl 中封裝下就變成了如今的 Messenger , 而咱們又在 Messenger 上封裝了下,想當於 三次封裝了,爲了使用更簡單。封裝纔是王道!
咱們本身的 YKProBus 爲了進程間通訊使用更簡單方便,其實至關於在 AIDL 中的三次封裝。想要了解的能夠去看下我具體的封裝或者 Messenger 源碼。
感謝你們抽空閱覽文章,謝謝!