同一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