Android框架层提供的一些通信机制Broadcast、Intent、Content Provider,主要用于应用程序开发时提供跨进程或应用程序内部的通信。
android中,通过广播(broadcast)可以通知广播接受者某个事件发生了。比如一些系统时间:电源不足,时间改变等,也可以是自定义的事件。
有两种方式可以注册:静态注册(冷注册)和动态注册(热注册)。
l 冷注册,就是Broadcast Receiver的相关信息写在配置文件中,系统会负责在相关事件发生的时候及时通知到该Broadcast Receiver。这种模式适合于这样的场景:某事件发生 -> 通知Broadcast -> 启动相关处理应用。比如,监听来电、邮件、短信之类的,都隶属于这种模式。
l 热注册,顾名思义,注册这样的事情都是由应用自己来处理的,通常是在OnResume事件中通过registerReceiver进行注册,在OnPause等事件中通过unregisterReceiver反注册,通过这种方式使其能够在运行期间保持对相关事件的关注。比如,一款优秀的词典软件,可能会有在运行期间关注网络状况变化的需求,使其可以在有廉价网络的时候优先使用网络查询词汇,在其他情况下,首先通过本地词库来查词。而这样的监听,只需要在其工作状态下保持就好,不运行的时候,管你是天大的网路变化,与我何干。其模式可以归结为:启动应用 -> 监听事件 -> 发生时进行处理。
冷注册:
Activity中:
public class MainActivity extends Activity { public static final String NEW_LIFEFROM_DETECTED = "com.android.broadcasttest.BRDEMO1"; private int count=0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn=(Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent=new Intent(NEW_LIFEFROM_DETECTED); intent.putExtra("text", String.valueOf(count++)); sendBroadcast(intent); } }); }
继承一个Broadcast类
public class MyBroadReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Log.i("BROAD", "receive"); String str=intent.getStringExtra("text"); Toast.makeText(context, "receive:"+str, Toast.LENGTH_LONG).show(); } }
AndroidManifest中注册:
<receiver android:name=".MyBroadReceiver" > <intent-filter > <action android:name="com.android.broadcasttest.BRDEMO1"/> </intent-filter> </receiver>
热注册:
public class MainActivity extends Activity { BroadcastReceiver br=null; public static final String NEW_LIFEFROM_DETECTED = "com.android.broadcasttest.BRDEMO1"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn =(Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Date date=new Date(); String str=date.toLocaleString(); Log.i("btn", str); Intent intent=new Intent(NEW_LIFEFROM_DETECTED); intent.putExtra("demo2", str); sendBroadcast(intent); } }); br=new BroadcastReceiver() {//在onCreat()中定义 @Override public void onReceive(Context context, Intent intent) { System.out.println(intent.getStringExtra("demo2")); } }; } @Override protected void onResume() { super.onResume(); IntentFilter intentf=new IntentFilter(); intentf.addAction(NEW_LIFEFROM_DETECTED); //intentf.addAction(Intent.ACTION_TIME_TICK); registerReceiver(br, intentf);//在onResume()中注册 } @Override protected void onPause() { super.onPause(); unregisterReceiver(br);//不要忘了在onPause()中注销 }
测试结果:
从结果可以看到,点击按钮之后,通过Log.i("btn", str)打印了一行代码,然后通过Intent传到BroadCast中,通过System.out 打印结果
但最后一行又冒出来一句,PID是不同的,这是前一个Demo也接收到了这个事件(相同的标识)。但反过来,在第一个应用中点击send 第二个却接收不到。如果要让第一个不接受别的App的BroadCast,应将第一个的AndroidManifest中的receiver标签添加一个属性为:
<receiver android:name=".MyBroadReceiver" android:exported="false"> <intent-filter > <action android:name="com.android.broadcasttest.BRDEMO1"/> </intent-filter> </receiver>
如果要第二个APP能够接收到该Broadcast,那么要在AndroidManifest中添加uses-permission标签
需要注意的是,当Broadcast Receiver接收到相关的消息,在OnReceive中不要执行很消耗时间的操作,通常把消耗时间的操作放到一个Service中,在OnReceive中启动该Service。