Android IPCプロセス間通信メカニズムのMessenger

4944 ワード

Messengerはプロセス間通信ツールとして、Messageを相互に伝達することでプロセス間データの相互共有を行うことができます.AndroidにとってMessengerは軽い
レベルのIPC方式で、内部はAIDLをカプセル化した.その実現はAIDL方式よりも容易である.
1、サービス側WorkServiceの作成:
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class WorkService extends Service {
    
    public static final int MSG_FROM_CLIENT = 101;

    private Handler workHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_FROM_CLIENT:

                    Bundle bundle = msg.getData();
                    //           
                    Log.d("RJie", "WorkService: " + bundle.getString("msg"));
                    //   msg   msg.replyTo          Messenger   
                    Messenger workMessenger = msg.replyTo;

                    Message serviceMsg = Message.obtain(null, WorkService.MSG_FROM_CLIENT);

                    Bundle serviceBundle = new Bundle();

                    serviceBundle.putString("rep", "  ,     ,      !!!");

                    serviceMsg.setData(serviceBundle);

                    try {
                        //        
                        workMessenger.send(serviceMsg);

                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }

                    break;
            }

        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        //        Handler     Binder   
        return new Messenger(workHandler).getBinder();
    }

}

2、インベントリファイルにサービスを登録する:android:processは、サービス側とクライアントが異なるプロセスで実行されるように値を与えなければならない.
     

        

3、クライアントコード:
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.Process;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    //     Handler               
    private Handler mainHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case WorkService.MSG_FROM_CLIENT:
                    Log.d("RJie", "MainActivity: " + msg.getData().getString("rep"));
                    break;
            }
        }
    };

    private Messenger mainMessenger;

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

        //    UI        id

        Log.d("RJie", "MainActivity.pid==" + Process.myPid());

        //     
        Intent workServiceIntent = new Intent(MainActivity.this, WorkService.class);

        bindService(workServiceIntent, sc, Context.BIND_AUTO_CREATE);


    }
    //     ServiceConnection                    
    private ServiceConnection sc = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //   IBinder        Messenger   
            mainMessenger = new Messenger(service);

            Message mainMessage = Message.obtain(mainHandler, WorkService.MSG_FROM_CLIENT);

            Bundle mainBundle = new Bundle();

            mainBundle.putString("msg", "      ,     !!!");

            mainMessage.setData(mainBundle);
            //  Messenger         
            mainMessage.replyTo = new Messenger(mainHandler);

            try {
                //        
                mainMessenger.send(mainMessage);

            } catch (RemoteException e) {
                e.printStackTrace();
            }


        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //     
        unbindService(sc);
    }

}
実行結果:
06-16 20:18:54.907 3668-3668/? D/RJie: MainActivity.pid==3668
06-16 20:18:54.987 3688-3688/? D/RJie: WorkService.pid==3688
06-16 20:18:55.057 3688-3688/? D/RJie: WorkService:       ,     !!!
06-16 20:18:55.110 3668-3668/? D/RJie: MainActivity:   ,     ,      !!!

ここまで来ると、簡単なMessengerの使用が完了します.、