同一app内部的同一组件内的消息通讯(单个或多个线程之间):
使用扩展变量做用域、基于接口的回调仍是Handler-post/Handler-Message等方式java
同一app内部的不一样组件之间的消息通讯(单个进程):
EventBus因为是针对统一进程,用于处理此类需求很是适合,且轻松解耦。android
同一app具备多个进程的不一样组件之间的消息通讯
不一样app之间的组件之间消息通讯
Android系统在特定状况下与App之间的消息通讯:
1. 使用BroadcastReceiver安全
<receiver android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
. . .
</receiver>网络
android:enabled
启用或禁用某组件,也可使用PackageManager类的setComponentEnabledSetting方法:
ComponentName receiver = new ComponentName(context,须要禁止的receiver);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);app
android:exported
此broadcastReceiver可否接收其余App的发出的广播,其默认值是由receiver中有无intent-filter决定的,若是有intent-filter,默认值为true,不然为false。
(一样的,activity/service中的此属性默认值同样遵循此规则)同时,须要注意的是,这个值的设定是以application或者application user id为界的,而非进程为界(一个应用中可能含有多个进程);ide
android:name
此broadcastReceiver类名post
android:permission
若是设置,具备相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收ui
android:process
broadcastReceiver运行所处的进程,默认为app的进程。能够指定独立的进程(Android四大基本组件均可以经过此属性指定本身的独立进程).net
发送方:
<!-- 建立自定义受权 -->
<permission android:name="com.android.study.permission.MYRECEIVER"
android:protectionLevel="signature"/>
<!-- protectionLevel属性,经常使用的以下:
normal:默认的,应用安装前,用户能够看到相应的权限,但无需用户主动受权。
dangerous:normal安全级别控制之外的任何危险操做。须要dangerous级别权限时,Android会明确要求用户进行受权。常见的如:网络使用权限,相机使用权限及联系人信息使用权限等。
signature:它要求权限声明应用和权限使用应用使用相同的keystore进行签名。若是使用同一keystore,则该权限由系统授予,不然系统会拒绝。而且权限授予时,不会通知用户。它经常使用于应用内部。
signatureOrSystem: 系统级别 -->
<!-- 声明自定义权限 -->
<uses-permission android:name="com.android.study.permission.MYRECEIVER"/>线程
Intent intent = new Intent();
intent.setAction("com.android.study.action.IRECEIVER");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("data", "sendPermission");
sendBroadcast(intent, "com.android.study.permission.MYRECEIVER");
接收方:
<!-- 声明自定义权限 -->
<uses-permission android:name="com.android.study.permission.MYRECEIVER"/>
<!-- 静态注册receiver,使用自定义权限 -->
<receiver android:name="com.android.study.receiver.PermissionBroadcastReceiver"
android:permission="com.android.study.permission.MYRECEIVER"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="com.android.study.action.IRECEIVER" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("具备自定义权限的广播接收类——" + intent.getStringExtra("data"));
//TO DO
}
2. 使用AIDL和Messenger与远程Service通讯:
http://blog.csdn.net/jiwangkailai02/article/details/48098087
2.1 Messenger: 经过2个Messenger来实现轻量级的双向通讯,能够传递数据。
Server端:
<uses-permission android:name="org.xutils.sample.permission.RemoteService" />
<service android:name=".RemoteMessengerService"
android:permission="org.xutils.sample.permission.RemoteService"
android:enabled="true"
android:process=":remote">
<intent-filter>
<action android:name="org.xutils.sample.action.messagener"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
public class RemoteMessengerService extends Service {
public static final int SEND_MSG = 10;
public static final int RECEIVER_MSG = 100;
public class ServerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case RECEIVER_MSG:
client_messenger = msg.replyTo;
if ( client_messenger != null ) {
Message message = Message.obtain();
message.what = SEND_MSG;
try{
client_messenger.send(message);
} catch(Exception e) {
e.printStackTrace();
}
}
break;
default:
break;
}
}
}
public final Messenger server_messenger = new Messenger(new ServerHandler());// 用来接收Server端的数据
public Messenger client_messenger = null; // 用于向Client端发送数据
@Override
public IBinder onBind(Intent intent) { //检查自定义权限
int check = checkCallingOrSelfPermission("org.xutils.sample.permission.RemoteService");
if(check== PackageManager.PERMISSION_DENIED){
return null;
} else {
return server_messenger.getBinder();
}
}
}
Client端:
<permission android:name="org.xutils.sample.permission.RemoteService"
android:protectionLevel="signature" />
<uses-permission android:name="org.xutils.sample.permission.RemoteService" />
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bindMessengerService();
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindMessengerService();
}
public static final int SEND_MSG = 10;
public static final int RECEIVER_MSG = 100;
private void sendMsgToServer() {
if ( server_messenger != null ) {
Message message = new Message();
message.what = RECEIVER_MSG;
message.replyTo = client_messenger;
try {
server_messenger.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class ClientHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SEND_MSG:
break;
default:
break;
}
}
};
public Messenger client_messenger = new Messenger(new ClientHandler());// 用来接收Client端的数据
public Messenger server_messenger = null;// 用于向Server端发送数据
public ServiceConnection messengerConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName var1, IBinder binder) {
server_messenger = new Messenger(binder);
}
@Override
public void onServiceDisconnected(ComponentName var1) {
server_messenger = null;
}
};
private void bindMessengerService() {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction("org.xutils.sample.action.messagener");
ComponentName componentName = new ComponentName(
"me.yokeyword.sample",
"me.yokeyword.sample.RemoteMessengerService");
intent.setComponent(componentName);
bindService(intent, messengerConnection, BIND_AUTO_CREATE);
}
private void unbindMessengerService() {
if ( server_messenger != null ) {
unbindService(messengerConnection);
}
}
2.2 AIDL:经过定义2个aidl文件,实现双向通讯,能够回调接口。
http://blog.csdn.net/luoyanglizi/article/details/51980630
sourceSets{
main{
java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
Server端:
建立aidl自定义接口文件 — IClientAidlInterface.aidl和IServerAidlInterface.aidl
步骤:File –> New –> AIDL –> AIDL File
interface IClientAidlInterface {
String doSthInClient();
}
interface IServerAidlInterface {
String doSthInServer();
void registerClientCallback(IClientAidlInterface clientInterface);
void unregisterClientCallback(IClientAidlInterface clientInterface);
}
点击Build –> Make Module’server’
而后能够看到在build/generated/source/aidl/debug/me.yokeyword.sample/目录下生成了文件IClientAidlInterface和IServerAidlInterface,表示编译成功.
<uses-permission android:name="org.xutils.sample.permission.RemoteService" />
<service android:name=".RemoteAIDLService"
android:permission="org.xutils.sample.permission.RemoteService"
android:enabled="true"
android:process=":remote">
<intent-filter>
<action android:name="org.xutils.sample.action.aidl"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
public class RemoteAIDLService extends Service {
private RemoteCallbackList<IClientAidlInterface> mCallbacks =
new RemoteCallbackList<IClientAidlInterface>();
public class IMyServer extends IServerAidlInterface.Stub {
@Override
public String doSthInServer() throws RemoteException {
final int len = mCallbacks.beginBroadcast();
for ( int i = 0; i < len; i++ ) {
try {
String text = mCallbacks.getBroadcastItem(i).doSthInClient();
} catch (RemoteException e) {
e.printStackTrace();
}
}
mCallbacks.finishBroadcast();
return "This is server";
}
@Override
public void registerClientCallback(IClientAidlInterface clientInterface) {
mCallbacks.register(clientInterface);
}
@Override
public void unregisterClientCallback(IClientAidlInterface clientInterface) {
mCallbacks.unregister(clientInterface);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public Binder onBind(Intent intent) {//检查自定义权限
int check = checkCallingOrSelfPermission("org.xutils.sample.permission.RemoteService");
if(check== PackageManager.PERMISSION_DENIED){
return null;
} else {
return new IMyServer();
}
}
@Override
public void onDestroy() {
mCallbacks.kill();
super.onDestroy();
}
}
Client端:
将服务端配置的整个aidl目录一并拷贝到客户端所在工程src/main目录下(包名与文件名必须与服务端如出一辙)
点击Build –> Make Module’server’
而后能够看到在build/generated/source/aidl/debug/me.yokeyword.sample/目录下生成了一个文件IClientAidlInterface和IServerAidlInterface,表示编译成功.
<permission android:name="org.xutils.sample.permission.RemoteService"
android:protectionLevel="signature" />
<uses-permission android:name="org.xutils.sample.permission.RemoteService" />
private void doSthInServer(){
if ( myInterface!=null ) {
try {
String str = myInterface.doSthInServer();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private IClientAidlInterface client = new IClientAidlInterface.Stub(){
@Override
public String doSthInClient() {
return "This is Client";
}
};
private IServerAidlInterface myInterface = null;
public ServiceConnection aidlConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName var1, IBinder binder) {
myInterface = IServerAidlInterface.Stub.asInterface(binder);
try {
myInterface.registerClientCallback(client);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName var1) {
myInterface = null;
try {
myInterface.unregisterClientCallback(client);
} catch ( Exception e ) {
e.printStackTrace();
}
}
};
private void bindAIDLService() {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction("org.xutils.sample.action.aidl");
ComponentName componentName = new ComponentName(
"me.yokeyword.sample",
"me.yokeyword.sample.RemoteAIDLService");
intent.setComponent(componentName);
bindService(intent, aidlConnection, BIND_AUTO_CREATE);
}
private void unbindAIDLService() {
if ( myInterface!= null ) {
unbindService(aidlConnection);
}
}
http://blog.csdn.net/u012760183/article/details/51397014