广播,在咱们的应用中起着一个很是重要的角色。就好比说咱们常用的Intent
、IntentFilter
,就有着广播的做用。java
在个人Android工具包项目中就集成了网络广播的动态注册。android
由于没有直接的图示能够上,并且Broadcast中并无onCreate
、onDestroy
这样方法,只能经过官方文档验证。 git
Activity
中的具体操做相关。
在Android 8.0之后已经不在支持静态广播了github
public class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION) && App.getInstance() != null) {
App.getInstance().notifyObservers(isNetConnected(context));
}
}
}
复制代码
虽然是两种广播形式,可是他们一样要干一件事情,就是继承BroadcastReceiver
,并重写onReceive()
方法。安全
这个广播一样可使用在应用内,可是这种广播的安全性有待质疑。网络
// 消息传递
sendBroadcast(Intent);
复制代码
<receiver android:name="com.clericyi.basehelper.network.NetworkReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_LOW"/>
</intent-filter>
</receiver>
复制代码
和静态广播不一样的地方,动态广播注册完之后须要进行注销操做。异步
// 注册
networkReceiver = new NetworkReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(networkReceiver, intentFilter);
// 注销(若是没有注销,将会发生内存泄漏)
unregisterReceiver(networkReceiver);
复制代码
//注册
networkReceiver = new NetworkReceiver();
localBroadcastManager = LocalBroadcastManager.getInstance(this); // --> 以单例模式进行建立
localBroadcastManager.registerReceiver(networkReceiver, new IntentFilter("须要去过滤的信息"));
// 发送消息
localBroadcastManager.sendBroadcast(Intent);
// 注销
localBroadcastManager.unregisterReceiver(networkReceiver);
复制代码
为何要导读LocalBroadcastManager
源码呢?ide
实际上是想让读者们知道LocalBroadcastManager
使用并非Binder
机制来完成通讯的。函数
public static LocalBroadcastManager getInstance(@NonNull Context context) {
synchronized (mLock) {
if (mInstance == null) {
mInstance = new LocalBroadcastManager(context.getApplicationContext()); // 1 -->
}
return mInstance;
}
}
// 由注释1直接调用的方法
private LocalBroadcastManager(Context context) {
mAppContext = context;
mHandler = new Handler(context.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_EXEC_PENDING_BROADCASTS:
executePendingBroadcasts();
break;
default:
super.handleMessage(msg);
}
}
};
}
复制代码
那这里就是很清楚的知道,这是一个以DCL
的方式,来直接完成对单例的建立,而在构造函数中,定义了一个Handler
。工具
那咱们就来作一个猜想,咱们在应用内的广播本质实际上是基于一个Handler
的一异步传输机制。为了验证!!咱们就须要去了解他的sendBroadcast(Intent)
方法。
public boolean sendBroadcast(@NonNull Intent intent) {
synchronized (mReceivers) {
// 拿到传递过来的Intent中保存的数据
final String action = intent.getAction();
final String type = intent.resolveTypeIfNeeded(
mAppContext.getContentResolver());
final Uri data = intent.getData();
final String scheme = intent.getScheme();
final Set<String> categories = intent.getCategories();
// 。。。。。
// 获取配置的Action
ArrayList<ReceiverRecord> entries = mActions.get(intent.getAction());
if (entries != null) {
if (debug) Log.v(TAG, "Action list: " + entries);
ArrayList<ReceiverRecord> receivers = null;
// 。。。。。 对变量receivers的一些列操做。
// 存在接受对象时,将数据经过Handler的方式传递出去。
if (receivers != null) {
for (int i=0; i<receivers.size(); i++) {
receivers.get(i).broadcasting = false;
}
mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));
if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {
mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);
}
return true;
}
}
}
return false;
}
复制代码
经过代码已经成功验证了,其实LocalBroadcast
最终基于的数据传输机制就是咱们的Handler
,这就是和应用间广播最大的不一样之处了。
ANR
的惨状,广播的耗时操做时长不容许超过10s。并且广播内通常也不会像Service
和Activity
同样会使用Thread
来完成咱们的耗时操做。LocalBroadcast
)使用的Handler
的消息传输机制;应用间广播或者说是进程间广播(Broadcast
)使用的则是Binder
的机制。以上就是个人学习成果,若是有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。
相关文章推荐: