android四种常用的消息传递机制/模式的比较

来源:互联网 发布:模特接单软件 编辑:程序博客网 时间:2024/06/05 01:59

四种分别是callback interfacehandler-messagebroadcast receiverobserver-subject

1. callback interface

这种消息传递的方式,需要在接收方调用发送方的方法或者在创建实例时,将回调接口传入,并在接收方实现接口方法。
举例:
定义一个回调接口:

public interface ITest{    void doWhat();}

接受方:

public class Receiver implements ITest{    private Sender sender = null;    public void createSender(){        sender = new Sender(this);    }    @Override    public void doWhat(){        //TODO    }}

发送方:

public class Sender{    private ITest iTest = null;    public Sender(ITest iTest){        this.iTest = iTest;    }    public void doSth(){        iTest.doWhat();    }}

优点:代码量小,很容易理解,处理效率高。
缺点:不利于修改和扩展,接口一变更,发送方和接收方都需要修改参数。并且必须提供一个获取接口的入口。

2. handler-message

这种方式和第一种在构造时有相同之处,就是同样需要从接收方传给发送方
举例:
接受方:

public class Receiver implements ITest{    private Handler handler = new Handler(new Handler.Callback(){        @Override        public boolean handlerMessage(Message msg){            switch(msg.what){                case 0:                    String message = (String)msg.obj;                    Log.e("Receiver", message)                    break;                case 1:                    //TODO                    break;                default:                    break;            }            return true;        }    });    public void createSender(){        sender = new Sender(handler);    }}

发送方:

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);    }}

优点:无需去自定义接口,便于修改和扩展。
缺点:同样必须提供一个获取接口的入口。修改发送方数据后,在接收方存在数据类型转换异常的风险。

3. broadcast receiver

广播分动态注册和静态注册,这里讲动态注册。常用于两个业务层之间多个数据通信。广播的本质也是观察者模式。必须注意的是,为防止内存泄漏,需要及时注销接收器。
举例:
接收方:

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;            }        }    }}

发送方:

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,在接收时存在类型转换异常的风险。

4. observer-subject

观察者模式常用于一对多的消息群发。观察者是接收方,主题是发送方。同样需要及时注销防止内存泄漏。
举例:
定义一个观察者接口:

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。