Android中的IPC跨进程通讯

我们知道在Android开发中通讯传值是经常能够遇到的,像进程内部 进程与进程之间,如果是在进程内部 我们可以通过接口回调 或者EventBus来实现,尤其是第二个 在各个界面间传值非常方便,然而 如果是跨进程 的话他就隔屁了
什么时候应用会有多进程呢
比如在一个应用中要使用定位的功能,定位服务就可以交给一个进程去处理,第三方的服务都可以这样去提供,这样定位问题就很快了
在多进程中有多种实现方式比如自定义监听(不太现实),广播(用于进程唤醒)还有本文要讲述的Messenger(信使)
客户端发信息给服务端 ,服务端处理完之后再把反馈信息传递给客户端,然后客户端据此作出反馈
Messenger这个类的注释:
This allows for the implementation of message-based communication across processes允许实现基于消息的进程间通信的方式
我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。
这样的进程间通信是不是很爽呢?
1.基于Message,相信大家都很熟悉
2.支持回调的方式,也就是服务端处理完成长任务可以和客户端交互
3.不需要编写aidl文件
此外,还支持,记录客户端对象的Messenger,然后可以实现一对多的通信;甚至作为一个转接处,任意两个进程都能通过服务端进行通信
客户端代码:

/**
 * 如果需要服务跟远程进程通信,那么就可以使用Messenger对象来给服务提供接口。
 * 这种技术允许你在不使用AIDL的情况下执行进程间通信(IPC)。
 *以下是信使(Messenger)对象的使用概要:
 *1.服务端实现的一个处理器(Handler接口),这个处理器针对每次来自客户端的调用接收一次回调;
 *2.这个处理器被用于创建一个信使对象(Messager)(这个信使对象要引用这个处理器);
 *3.信使对象创建一个创建一个服务端从onBind()方法中返回给客户端的IBinder对象;
 *4.客户端使用这个IBinder对象来实例化这个信使对象(信使引用了服务端的处理器),
 * 客户端使用这个信使给服务端发送Message对象;
 *5.服务端在它的处理器(Handler)的handleMessage()方法中依次接收每个Message对象
 *在这种方法中,没有给客户端提供服务端的方法调用,相反,客户端会给发送服务端消息(Message)对象,
 * 服务端会在它的处理器中接受这些消息对象。
 */
public class Second extends AppCompatActivity{
    private TextView mTvState;
    private boolean isConn;
    private MyConn conn;
    // 客户端的信使
    private Messenger clientMessenger;
    // 客户单的"地址":
    private Messenger clientAddress = new Messenger(new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 2:
                    int serverMsg = msg.arg1;
                    Log.i("TAG", "服务端回复的消息=" + serverMsg);
                    break;
            }
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        mTvState = (TextView) findViewById(R.id.mTvState);
    }

    // 按钮点击事件种,进行信息的传递:"青鸟发消息给吴刚"
    public void communication(View v) {
        try {
            // 客户端的消息
            Message clientMsg = Message.obtain();
            clientMsg.what = 1;
            clientMsg.arg1 = 100;
            // 客户端要告诉服务端:我自己的地址是....
            clientMsg.replyTo = clientAddress;
            // 客户端的信使给服务端的信使发消息
            if(isConn){
                clientMessenger.send(clientMsg);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Intent service = new Intent("messenger");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            service.setPackage("com.longlian.messenger");
        }
        conn = new MyConn();
        bindService(service, conn, BIND_AUTO_CREATE);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (conn != null) {
            unbindService(conn);
        }
    }

    // 客户端和服务端建立连接
    class MyConn implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 得到客户端的信使---->青鸟
            clientMessenger = new Messenger(service);
            isConn = true;
            mTvState.setText("connected!");
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            clientMessenger = null;
            isConn = false;
            mTvState.setText("disconnected!");
        }
    }
}

//服务端代码

public class MessengerServer extends Service {

    // 信使--->青鸟殷勤为探看
    // 服务端的信使:----->"吴刚"
    private Messenger serverMessenger = new Messenger(new ServerHandler());
    // 服务端进行消息的处理和发送
    class ServerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case 1:
                // 取出客户端发送过来的消息
                int clientMsg = msg.arg1;
                Log.i("TAG", "客户端的消息=" + clientMsg);
                // 服务端给客户端回复信息
                // 取出客户端的"地址"
                Messenger clientAddress = msg.replyTo;
                try {
                    // 服务端的信息
                    Message serverMsg = Message.obtain();
                    serverMsg.what = 2;
                    serverMsg.arg1 = 200;
                    // 给客户端回复信息
                    clientAddress.send(serverMsg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        return serverMessenger.getBinder();//获取IBinder对象.
    }
}

在清单文件注明服务端是在单独的进程中

<service android:name=".MessengerServer"
         android:enabled="true"
                 android:exported="true"  >
            <intent-filter>
                <action android:name="messenger" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>

周一快乐

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值