前言
由于Android系统中应用程序之间不能共享内存。因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些。
在android SDK中提供了4种用于跨进程通讯的方式。这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。
- Activity可以跨进程调用其他应用程序的Activity;
- Content Provider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操 作;
- Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播;
- Service和Content Provider类似,也可以访问其他应用程序中的数据,但不同的是,Content Provider返回的是Cursor对象,
- Service返回的是Java对象,这种可以跨进程通讯的服务叫AIDL服务。
问题
我的同学遇到了两个应用程序进行通讯的问题,下面为解决这个问题所做一下总结。
事情是这样的他们公司有两个不同的应用需要通讯,这里是要用广播方式来实现。 他的广播是在AndroidManifest
中静态注册的因为他需要在程序没有运行时做一些事情,同时呢如果应用正在运行时还需要UI做动态的更新,这就是问题了的所在了。
解决
开始的问题是在 BroadcastReceiver的 onReceive中根本获取不到UI的对象,平时写BroadcastReceiver都是在Activity中直接写了,就需要传递参数了。
我这里呢是使用接口的形式来实现的。首先定义一个接口,接口中就是广播接收器发送来的内容。
public interface ISendMessage {
public void send(String message);
}
我这里是用插拔USB的方式来来触发广播。然后把数据通过接口来发送。
public class StartBroadcastReceiver extends BroadcastReceiver {
public static final String ACTION = "Android.intent.action.BOOT_COMPLETED";
public static final String SEND_ACTION = "Android.intent.action.SEND_MESSAGE";
public static final String MESSAGE = "MESSAGE";
private ISendMessage iSendMessage;
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION)) {
if (true) {// 用户已经登陆
NotificationService.startService(context);
}
} else if (intent.getAction().equals(SEND_ACTION)) {
String message = intent.getStringExtra(MESSAGE);
iSendMessage.send(message);
}
}
public void setSendMessageListener(ISendMessage iSendMessage) {
this.iSendMessage = iSendMessage;
}
}
下面别忘了在AndroidManifest文件中静态注册
<receiver android:name="org.androidpn.client.StartBroadcastReceiver" >
<intent-filter>
<action android:name="Android.intent.action.SEND_MESSAGE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 下面是注册监听器的代码。
private StartBroadcastReceiver startBroadcastReceiver = new StartBroadcastReceiver();
/**
* 注册监听器
*
* @param textView
*/
/**
* 注册监听器且注册广播
*
* @param textView
*/
private void regListenerAndReceiver() {
IntentFilter intentFilter = new IntentFilter(
StartBroadcastReceiver.SEND_ACTION);
registerReceiver(startBroadcastReceiver, intentFilter);
startBroadcastReceiver.setSendMessageListener(new ISendMessage() {
@Override
public void send(String message) {
Log.v(LOGTAG, "sendMessage:" + message);
sendMessage(message);
}
});
}
解除注册监听器
unregisterReceiver(startBroadcastReceiver);
接着呢下面发送广播。
Intent intent=new Intent(StartBroadcastReceiver.SEND_ACTION);
intent.putExtra(StartBroadcastReceiver.MESSAGE, "你好,钓鱼岛是中国的!");
DemoAppActivity.this.sendBroadcast(intent);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
android广播动态与静态注册小知识
android的广播分为静态注册和动态注册两种方式,具体的操作方式网上有非常多的案例。这里主要记录一下他们的一些特殊的小知识。
1.动态注册和静态注册可以同时进行,简单来说就是使用一个Receiver分别在
AndroidManifast
中进行注册,又写入在程序中用代码注册(无论Action是否相同),两种注册方式不会造成影响。动态注册只会在程序存在时执行,静态注册一直执行。哪怕是完全相同的Receiver。即如果程序存在,该Receiver会被执行两次。2.动态注册使用同一个Receiver对象,从开始创建直到其被解除注册。会使用同一个Receiver,无论这个广播被触发几次。而静态注册则每次触发都会建立新的Receiver对象。
3.
android.intent.action.SCREEN_ON
与android.intent.action.SCREEN_OFF
不可以使用静态注册(没有效果),必须使用动态注册的方式。可能是由于android的内部管理机制导致,不希望程序在未运行时还保持对屏幕的监视。