天天看點

Android基礎——Messenger在跨程序通信中的使用

Messenger在跨程序通信中的使用

事先說明:

本人也是個初學者,是以本文是從初學者的角度入手,如果有不妥的地方請留言教導我,謝謝。

本篇文章主要針對講解Messenger的使用和Messenger在應用層上的原了解析和Messenger在服務端的回複。

什麼是Messenger?

Messenger可以翻譯為信使,Messenger是一種輕量級的IPC方案,通過它可以在不同程序中傳遞Message對象,在Message中放入我們需要傳遞的資料,就可以實作資料的程序間傳遞了。

步驟一:Messenger的使用

服務端的編寫:

public class MessagerService extends Service {

    //辨別
    public static final int GET_RESULT = 1;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }

    private final Messenger mMessenger = new Messenger(new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case GET_RESULT:
                    Log.i("服務端的消息:" , msg.getData().getString("data"));
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    });
}
           

在manifests中配置service:

<service
            android:name=".Messager.MessagerService"
            android:exported="true" />
           

用戶端的編寫(在另一個應用中):

public class MessengerActivity extends AppCompatActivity {

    //辨別
    public static final int GET_RESULT = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);

        //綁定服務
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.handsome.boke", "com.handsome.boke.Messager.MessagerService"));
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    /**
     * 服務回調方法
     */
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //獲得消息者
            Messenger messenger = new Messenger(service);
            //建立空消息
            Message message = Message.obtain(null, GET_RESULT);
            Bundle bundle = new Bundle();
            bundle.putString("data", "這是用戶端發過去的消息");
            //往消息中存資料
            message.setData(bundle);
            //消息者發送消息
            try {
                messenger.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解綁服務,回收資源
        unbindService(conn);
    }
}
           

啟動服務端的Activity,并開啟服務:

public class LoginActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        startService(new Intent(this, MessagerService.class));
    }
}
           

接着啟動用戶端,檢視測試結果:

08-21 06:18:25.521 4154-4154/com.handsome.boke I/服務端的消息:: 這是用戶端發過去的消息
           

步驟二:Messenger在應用層上的原了解析

我們追随到Messenger的建立方法中,檢視源碼可以知道,底層是使用AIDL:

/**
     * Create a Messenger from a raw IBinder, which had previously been
     * retrieved with {@link #getBinder}.
     * 
     * @param target The IBinder this Messenger should communicate with.
     */
    public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }
           

關于AIDL的使用和原理分析,這裡參照我的CSDN部落格,裡面有詳細的分析,Android基礎——初學者必知的AIDL在應用層上的Binder機制,http://blog.csdn.net/qq_30379689/article/details/52253413

步驟三:Messenger可以接受到用戶端的消息後進行回複,這裡就類似于郵箱自動回複的功能

改一下服務端的代碼:

public class MessagerService extends Service {

    //辨別
    public static final int GET_RESULT = 1;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }

    private final Messenger mMessenger = new Messenger(new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case GET_RESULT:
                    Log.i("服務端的消息:" , msg.getData().getString("data"));
                    //------------------------修改的代碼----------------------
                    //接受到消息後,進行回複
                    //通過replyTo拿到Messenger對象
                    Messenger messenger = msg.replyTo;
                    Message message = Message.obtain(null,GET_RESULT);
                    Bundle bundle = new Bundle();
                    bundle.putString("reply","好的,我收到你的資訊了");
                    message.setData(bundle);
                    try {
                        messenger.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    });
}
           

改一下用戶端的代碼:

public class MessengerActivity extends AppCompatActivity {

    //辨別
    public static final int GET_RESULT = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);

        //綁定服務
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.handsome.boke", "com.handsome.boke.Messager.MessagerService"));
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    /**
     * 服務回調方法
     */
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //獲得消息者
            Messenger messenger = new Messenger(service);
            //建立空消息
            Message message = Message.obtain(null, GET_RESULT);
            Bundle bundle = new Bundle();
            bundle.putString("data", "這是用戶端發過去的消息");
            //---------------------------修改的代碼--------------------------
            message.replyTo = replyMessenger;
            //往消息中存資料
            message.setData(bundle);
            //消息者發送消息
            try {
                messenger.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解綁服務,回收資源
        unbindService(conn);
    }

    //---------------------------修改的代碼--------------------------
    private Messenger replyMessenger = new Messenger(new MessengerHandler());

    private static class MessengerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case GET_RESULT:
                    Log.i("用戶端的消息:", msg.getData().getString("reply"));
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    }
}
           

檢視我們的測試結果:

08-21 07:34:51.032 12808-12808/com.handsome.boke I/服務端的消息:: 這是用戶端發過去的消息
           
08-21 07:34:51.224 12784-12784/com.handsome.app2 I/用戶端的消息:: 好的,我收到你的資訊了
           

繼續閱讀