BroadcastReceiver安全问题
在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。我们拿广播电台来做个比方。我们平常使用收音机收音是这样的:许许多多不同的广播电台通过特定的频率来发送他们的内容,而我们用户只需要将频率调成和广播电台的一样就可以收听他们的内容了。Android中的广播机制就和这个差不多的道理。
BroadcastReceiver
设计的初衷是从全局考虑可以方便应用程序和系统、应用程序之间、应用程序内的通信,所以对单个应用程序而言 BroadcastReceiver
是存在安全性问题的(恶意程序脚本不断的去发送你所接收的广播)。为了解决这个问题 LocalBroadcastManager
就应运而生了。
LocalBroadcastManager
LocalBroadcastManager
是Android Support包提供了一个工具,用于在同一个应用内的不同组件间发送Broadcast。LocalBroadcastManager也称为局部通知管理器,这种通知的好处是安全性高,效率也高,适合局部通信,可以用来代替Handler更新UI。
好处:
- 因广播数据在本应用范围内传播,你不用担心隐私数据泄露的问题。
- 不用担心别的应用伪造广播,造成安全隐患。
- 相比在系统内发送全局广播,它更高效。
LocalBroadcastManager用法
LocalBroadcastManager对象的创建:
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance( this ) ;
注册广播接收器:
LocalBroadcastManager.registerReceiver( broadcastReceiver , intentFilter );
发送广播:
LocalBroadcastManager.sendBroadcast( intent ) ;
取消注册广播接收器:
LocalBroadcastManager.unregisterReceiver( broadcastReceiver );
代码示例:
通过广播实现两个Activity之间的通信:点击按钮,发送一个广播,广播行为的名字为com.example.update,使得前面界面的TextView中的文字改变
注意:如果仅仅实现此功能的话可以不使用广播,使用 startActivityForResult
和 onActivityResult
就可以。这里是为了演示广播。
BroadActivity2
实现点击按钮,发送广播:
public class BroadActivity2 extends AppCompatActivity {
private Button mBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broad2);
mBtn=findViewById(R.id.btn_click);
//点击按钮之后发送广播com.example.update(这个是任意取的)
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.update");
LocalBroadcastManager.getInstance(BroadActivity2.this).sendBroadcast(intent);
}
});
}
}
BroadActivity
实现接受指定广播:
public class BroadActivity extends AppCompatActivity {
private Button mBtn1;
private TextView mTvTest;
private MyBroadcast mBroadcast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broad);
mBtn1=findViewById(R.id.btn1);
mTvTest=findViewById(R.id.tv_test);
mBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(BroadActivity.this,BroadActivity2.class);
startActivity(intent);
}
});
//注册广播,如果有人发送广播的行为为"com.example.update",则接受该广播
mBroadcast = new MyBroadcast();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.update");
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcast,intentFilter);
}
//接受广播后的处理,TextView中的文本变为123
private class MyBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()){
case "com.example.update":
mTvTest.setText("123");
break;
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册广播,防止内存泄漏
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcast);
}
}
运行效果:
注意事项
虽然 LocalBroadcastManager
也通过 BroadcastReceiver
来接收消息,但是他们两个之间还是有很多区别的。
LocalBroadcastManager
注册广播只能通过代码注册的方式。传统的广播可以通过代码和xml两种方式注册。LocalBroadcastManager
注册广播后,一定要记得取消监听。这一步可以有效的解决内存泄漏的问题。LocalBroadcastManager
注册的广播,您在发送广播的时候务必使用LocalBroadcastManager.sendBroadcast(intent);
否则您接收不到广播。传统的发送广播的方法:context.sendBroadcast( intent );
。