Android開發中,有時會遇到組件之間相互通訊回調的問題。通常都是經過Android提供的ResultReceiver來實現(ResultReceiver的使用方法很簡單,這裏就很少提了)。android
但以前在工做中,遇到了一個組件間回調的問題,ResultReceiver沒法知足需求。簡單描述一下問題:service中打開了一個activity,activity須要將一個變量值回調給service,並且這個回調必須是同步的。也就是說activity在確認service接收到了這個變量值後,才能繼續向下執行代碼。衆所周知ResultReceiver的send方法是異步的,send方法執行後,接收方可能尚未收到消息。這樣"不及時"的回調在個人項目中可能會形成狀態不一樣步。git
那麼,只能本身實現一個同步的回調通訊。github
同步的回調通訊代碼以下:app
github地址:https://github.com/yuhaiyang89/yhy-utils異步
1.定義一個AIDLide
package com.yhy.utils; interface IChannel { void send(int code, in Bundle data); }
2.定義一個類,實現Parcelable(實現Parcelable是爲了能讓該類在組件中傳遞),並在此類中實現第一步定義的AIDL(經過這個AIDL完成回調)this
package com.yhy.utils.demo; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import com.yhy.utils.IChannel; public class SyncResultReceiver implements Parcelable { public static final Parcelable.Creator<SyncResultReceiver> CREATOR = new Parcelable.Creator<SyncResultReceiver>() { public SyncResultReceiver createFromParcel(Parcel in) { return new SyncResultReceiver(in); } public SyncResultReceiver[] newArray(int size) { return new SyncResultReceiver[size]; } }; // 是本地回調仍是遠程回調 final boolean mLocal; IChannel mBridge; public SyncResultReceiver() { mLocal = true; } SyncResultReceiver(Parcel in) { mLocal = false; mBridge = IChannel.Stub.asInterface(in.readStrongBinder()); } public void send(int code, Bundle data) { if (mLocal) { onReceiveResult(code, data); return; } if (mBridge != null) { try { mBridge.send(code, data); } catch (Exception e) { Log.e("", "",e); } } } protected void onReceiveResult(int code, Bundle bundle) { // 等待子類去實現此方法,接收消息 } public int describeContents() { return 0; } public void writeToParcel(Parcel out, int flags) { synchronized (this) { if (mBridge == null) { mBridge = new MyChannel(); } out.writeStrongBinder(mBridge.asBinder()); } } class MyChannel extends IChannel.Stub { public void send(int code, Bundle data) { onReceiveResult(code, data); } } }
實現完畢!spa
下面就可使用SyncResultReceiver來實現同步回調了code
例:MainActivity中打開Activity2,Activity2將一些消息同步的回調給MainActivityblog
MainActivity代碼:
package com.yhy.utils.demo; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; public class MainActivity extends AppCompatActivity { private int value = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 重寫SyncResultReceiver的onReceiveResult方法接收返回值 SyncResultReceiver mResultReceiver = new SyncResultReceiver(){ @Override protected void onReceiveResult(int code, Bundle bundle) { value = bundle.getInt("value"); Log.d("TEST", "code=" + code + " | value = " + value); } }; // 開啓Activity2 Intent intent = new Intent(this, Activity2.class); intent.putExtra("callback", mResultReceiver); startActivity(intent); } }
Activity2代碼:
package com.yhy.utils.demo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class Activity2 extends AppCompatActivity { SyncResultReceiver mReceiver = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mReceiver = getIntent().getParcelableExtra("callback"); // 給MainActivity回調值 Bundle bundle = new Bundle(); bundle.putInt("value", 1); mReceiver.send(1, bundle); } @Override protected void onStart() { super.onStart(); // 給MainActivity回調值 Bundle bundle = new Bundle(); bundle.putInt("value", 2); mReceiver.send(1, bundle); } @Override protected void onDestroy() { // 給MainActivity回調值 Bundle bundle = new Bundle(); bundle.putInt("value", 3); mReceiver.send(1, bundle); super.onDestroy(); } }
LOG輸出:
03-03 11:50:28.780 2790-2790/? D/TEST: code=1 | value = 103-03 11:50:28.782 2790-2790/? D/TEST: code=1 | value = 203-03 11:53:07.588 2790-2790/? D/TEST: code=1 | value = 3