一、android中使用广播的方式:
在android应用开发过程中,一般开发者使用广播的方式分为以下几个步骤:
1、自定义广播
public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String TAG = "MyBroadcastReceiver";
public static int m = 1;
@Override
public void onReceive(Context context, Intent intent) {
Log.w(TAG, "intent:" + intent);
String name = intent.getStringExtra("name");
Log.w(TAG, "name:" + name + " m=" + m);
m++;
Bundle bundle = intent.getExtras();
}
}
2、在activity或者fragment中使用广播。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BROADCAST_ACTION);
registerReceiver(mBroadcastReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mBroadcastReceiver);
}
实际上,需要使用这广播,还需要到AndroidManifest文件中注册广播,还需要添加addAction,等等,不难看出,这个过程中包含了比较多的细节,对于比经常使用广播的开发者来说,一旦一个需求需要使用到全局通知,就不得不去查阅相关资料来回顾广播如何使用。
二、那么有没有一种方式可以不使用android广播,而能够实现全局通知的功能呢?
我们先不妨整理一下需求:
- 简单易用
- 消息可以传递数据
- 高效
- 消息在主线程处理
有了以上需求中的一些关键字眼消息
+主线程
,其实,我们蛮容易想到Handler
以及MainLooper
的。
实现原理
让handler在MainLooper中转起来,那么,发送消息的话,将会在主线程中处理,handlerMessage的时候,在交给外部的listener去处理,实际上就实现需求了。
public final void send(final int id, @NonNull final Object payload) {
mHandler.sendMessage(mHandler.obtainMessage(id, payload));
}
@Override
public boolean handleMessage(@NonNull final Message msg) {
mMessage.setMessage(msg);
// process universal listeners
synchronized (mListenersUniversal) {
mDefensiveCopyList.clear();
mDefensiveCopyList.addAll(mListenersUniversal);
for (final LocalMessageCallback callback : mDefensiveCopyList) {
callback.handleMessage(mMessage);
}
// leave the list empty - prevent leaks
mDefensiveCopyList.clear();
}
mMessage.setMessage(null);
return true;
}
上述代码中:
1、send及表示发送消息,消息体中可以带上数据object,这里也不限制为Parceable / Serializable / Bundle类型,其实主要原因是因为这里不用实现跨进程通信。
2、handlerMessage中处理实际上已经将环境切换到了主线程中,拿到消息之后,进而直接转发给消息监听者处理即可。
三、既然说了使用简单,那么,到底是如何的简单呢,talk is cheap,show me the code
监听消息
public class MainActivity extends AppCompatActivity implements LocalMessageCallback {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(android.R.id.text1);
LocalMessageManager.getInstance().addListener(this);
// You can also listen to a specific message
// LocalMessageManager.getInstance().addListener(R.id.msg_sample_event, mSimpleMessageListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
LocalMessageManager.getInstance().removeListener(this);
// You can also listen to a specific message
// LocalMessageManager.getInstance().removeListener(R.id.msg_sample_event, mSimpleMessageListener);
}
@Override
public void handleMessage(@NonNull final LocalMessage msg) {
switch (msg.getId()) {
case R.id.msg_sample_event: {
mTextView.setText("Received simple event (" + System.currentTimeMillis() / 100 + ")");
}
break;
case R.id.msg_custom_payload_event: {
mTextView.setText("Received custom object (" + ((MyCustomObject) msg.getObject()).getSomeValue() + ")");
}
}
}
}
发送消息
view.findViewById(R.id.btn_fire_custom).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LocalMessageManager.getInstance().send(R.id.msg_custom_payload_event, new MyCustomObject());
}
});
四、重复造轮子总是不被待见的,在github上搜索了一下,发现居然有人已经实现了这样的一个库,而且思路基本上和自己的一致。
因此,如果是使用android studio开发的话,直接:
compile 'eu.inloop:localmessagemanager:0.1.7'
即可用上这么简单的广播系统了。