消息通訊

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

相關文章
相關標籤/搜索