现在的位置: 首页 > 综合 > 正文

[心得]Android进程间通信之Broadcast Receiver

2017年11月28日 ⁄ 综合 ⁄ 共 3223字 ⁄ 字号 评论关闭

Android框架层提供的一些通信机制BroadcastIntentContent Provider,主要用于应用程序开发时提供跨进程或应用程序内部的通信。

android中,通过广播(broadcast)可以通知广播接受者某个事件发生了。比如一些系统时间:电源不足,时间改变等,也可以是自定义的事件。

有两种方式可以注册:静态注册(冷注册动态注册(热注册)。

冷注册,就是Broadcast Receiver的相关信息写在配置文件中,系统会负责在相关事件发生的时候及时通知到该Broadcast Receiver。这种模式适合于这样的场景:某事件发生 -> 通知Broadcast -> 启动相关处理应用。比如,监听来电、邮件、短信之类的,都隶属于这种模式。 

热注册,顾名思义,注册这样的事情都是由应用自己来处理的,通常是在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 第二个却接收不到。如果要让第一个不接受别的AppBroadCast,应将第一个的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

抱歉!评论已关闭.