四種分別是callback interface,handler-message,broadcast receiver和observer-subject。ide
這種消息傳遞的方式,須要在接收方調用發送方的方法或者在建立實例時,將回調接口傳入,並在接收方實現接口方法。
舉例:
定義一個回調接口:this
public interface ITest{ void doWhat(); }
接受方:spa
public class Receiver implements ITest{ private Sender sender = null; public void createSender(){ sender = new Sender(this); } @Override public void doWhat(){ //TODO } }
發送方:code
public class Sender{ private ITest iTest = null; public Sender(ITest iTest){ this.iTest = iTest; } public void doSth(){ iTest.doWhat(); } }
優勢:代碼量小,很容易理解,處理效率高。
缺點:不利於修改和擴展,接口一變動,發送方和接收方都須要修改參數。而且必須提供一個獲取接口的入口。server
這種方式和第一種在構造時有相同之處,就是一樣須要從接收方傳給發送方。
舉例:
接受方:接口
發送方:內存
public class Sender{ private Handler handler = null; public Sender(Handler handler){ this.handler = handler; } public void doSth(){ Message msg = new Message(); msg.what = 0; msg.obj = "Hello world!"; handler.sendMessage(msg); } }
優勢:無需去自定義接口,便於修改和擴展。
缺點:一樣必須提供一個獲取接口的入口。修改發送方數據後,在接收方存在數據類型轉換異常的風險。rem
廣播分動態註冊和靜態註冊,這裏講動態註冊。經常使用於兩個業務層之間多個數據通訊。廣播的本質也是觀察者模式。必須注意的是,爲防止內存泄漏,須要及時註銷接收器。
舉例:
接收方:get
public class ReceiverActivity extends AppCompatActivity{ private TestReceiver receiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); receiver = new TestReceiver(); IntentFilter filter = new IntentFilter(/*這裏填你自定義的這個廣播過濾的名字NAME*/); registerReceiver(receiver, filter); } @Override protected void onDestroy() { super.onDestroy(); //很是重要!!!!!!!!!! unregisterReceiver(receiver); } public class TestReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String type = intent.getStringExtra(/*這裏填你自定義的發送消息的類型TYPE*/); switch(type){ case "TYPE1": int i = intent.getIntExtra("testInteger", 0); break; case "TYPE2": String s = intent.getStringExtra("testString"); break; default: break; } } } }
發送方:it
public class SendService extends Service{ public void doSth1(){ Intent intent = new Intent(/*這裏填剛纔你寫的那個NAME*/); intent.putExtra(/*這裏填剛纔你寫的那個消息類型TYPE*/,"TYPE1"); intent.putExtra("testInteger", 1); sendBroadcast(intent); } public void doSth2(){ Intent intent = new Intent(/*這裏填剛纔你寫的那個NAME*/); intent.putExtra(/*這裏填剛纔你寫的那個消息類型TYPE*/,"TYPE2"); intent.putExtra("testString", "Hello world!"); sendBroadcast(intent); } }
優勢:發送方和接收方實現了徹底解耦,發送方將消息發送出去後,這條消息就與他無關了,收沒收到也無論。
缺點:廣播的接收和發送得依賴context的環境。每次調用都須要寫繁瑣的intent和putExtra。數據傳遞方式類比handler,在接收時存在類型轉換異常的風險。
觀察者模式經常使用於一對多的消息羣發。觀察者是接收方,主題是發送方。一樣須要及時註銷防止內存泄漏。
舉例:
定義一個觀察者接口:
public interface Observer{ void newMsg(String msg); }
定義一個主題接口:
public interface Subject{ void addObserver(Observer observer); void removeObserver(Observer observer); void notify(String msg); }
定義一個觀察者管理類實現主題接口:
public class ObserverManager implements Subject{ private static ObserverManager instance = null; private List<Observer> Observers = new ArrayList<>(); private ObserverManager(){ } public static ObserverManager getInstance() { if (null == instance) { synchronized (ObserverManager.class) { if (null == instance) { instance = new ObserverManager(); } } } return instance; } @Override public void addObserver(Observer observer){ Observers.add(observer); } @Override public void removeObserver(Observer observer){ Observers.remove(observer); } @Override public void notify(String msg){ for(Observer observer: Observers){ observer.newMsg(msg); } } }
觀察者即接收方:
public class ObserverActivity extends AppCompatActivity implements Observer{ private ObserverManager manager = ObserverManager.getInstance(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); manager.addObserver(this); } @Override protected void onDestroy() { super.onDestroy(); //很是重要!!!!!!!!!! manager.removeObserver(this); } @Override public void newMsg(String msg){ Log.e("Get a new msg", msg); } }
主題即發送方:
public class Sender{ private ObserverManager manager = ObserverManager.getInstance(); public void sendNewMsg(){ manager.notify("This is a new msg from sender."); } }
優勢:同廣播,高度解耦。接口自定義,擴展性強。 缺點:一對一時或者接收方數量少時,「殺雞焉用牛刀」。接口修改時須要處處改動,同callback。