Android的跨进程通信介绍----------------aidl,传递复杂对象以及Server和Clicent之间的回调

来源:互联网 发布:开淘宝店技巧 编辑:程序博客网 时间:2024/05/16 07:06

Android的跨进程通信———aidl

做android也有一段时间了,一直没有在博客中去做过这样的总结,刚好这段时间学习开始总结点东西,想着一些简单的问题就不在上面总结了,而之前一些写的都是关于C一方面的总结,几乎看不到Android相关的,今天在这也就给大家分享一下,一个简单的跨进程通信的案例,aidl

其实Android的IPC机制最初应该是引用自Linux中的Ipc概念吧。做过Linux开发的人可能对这个IPC相对来说更加的清晰,什么是FIFO,PIPO管道啊,操作共享内存区域啊等等,都是源自Linux的

最近刚好在做一个跨进程通信用aidl进行重构优化的项目,所以对这一块可能比之前对aidl的了解又更深一步了吧。以前只是单纯的绑定,基本上没有用到server和Client之间的回调,以及也没有用到过于复杂对象的序列化。

首先我们来讲一下整体流程:

1:Client去绑定Server端
2:Server端在绑定过后,返回aidl的接口对象
3:Client将参数(json字符串)传递给Server端,在Server端去做处理
4:Server端然后再将处理的结果回调给Client

注意:Json字符串本来就是可以序列化的,所以这个时候我们可以剖除掉复杂的序列化的过程

带着问题讨论下:

1:aidl的传递复杂对象的时候是需要进行序列化的,也就是Parcelable接口,但是会有一个问题,如果这个对象过于复杂,在对象里面不断的包含另外一个对象,或者Map和List进行多层嵌套的时候,可能序列化就会出现问题
2:关于CallBack的回调,也就是Server回调给Client,它是一个类似aidl文件的接口。

这是我写的一个很简单的关于aidl整个流程的一个Demo,也是我在项目中用到的大概的整个流程吧:

IServer.aidl文件

package com.example.aidl;import com.example.aidl.IServerCallback;interface IServer{    void setAddNum(int num1,int num2);    void registerServerCallBack(IServerCallback callback);    void unregisterServerCallBack(IServerCallback callback);    void setString(String jsonString);}

IServerCallback.aidl文件:

package com.example.aidl;interface IServerCallback{    void setResult(int result);    void setTransferString(String jsonString);}

Server端代码:
MyCustomServer.java文件

package com.example.aidl2;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteCallbackList;import android.os.RemoteException;import android.util.Log;import com.example.aidl.IServer;import com.example.aidl.IServerCallback;public class MyCustomServer extends Service{    int Result = 0;    IServerCallback cback;    private final RemoteCallbackList<IServerCallback> mCallbacks      = new RemoteCallbackList<IServerCallback>();      @Override    public void onCreate() {        // TODO Auto-generated method stub        Log.i("123", "oncreate");        super.onCreate();    }    @Override    public IBinder onBind(Intent arg0) {        Log.i("123", "onBind");        return new MyCustomImpl();    }    @Override    public boolean onUnbind(Intent intent) {        // TODO Auto-generated method stub        return super.onUnbind(intent);    }    Plus plus;    private class MyCustomImpl extends IServer.Stub{        @Override        public void setAddNum(int num1, int num2) throws RemoteException {            // TODO Auto-generated method stub            Result  = num1 + num2;            Log.i("123", "RESULT:"+Result);            plus = new Plus(cback);            plus.add(num1, num2);//          if(cback != null){//              cback .setResult(plus.add(num1, num2));//          }        }        @Override        public void registerServerCallBack(IServerCallback callback) throws RemoteException {            // TODO Auto-generated method stub            Log.i("123","register callback");            if(callback != null){                mCallbacks.register(callback);                cback = callback;            }        }        @Override        public void unregisterServerCallBack(IServerCallback callback) throws RemoteException {            // TODO Auto-generated method stub            Log.i("123","unregister callback");            if(callback!=null){                   mCallbacks.unregister(callback);                     cback = null;            }        }        @Override        public void setString(String jsonString) throws RemoteException {            // TODO Auto-generated method stub            if(plus == null){                plus = new Plus(cback);            }            plus.getResult(jsonString);        }    }    @Override    public void onDestroy() {        // TODO Auto-generated method stub        super.onDestroy();    }   }

Plus.java

package com.example.aidl2;import android.os.RemoteException;import com.example.aidl.IServerCallback;import com.google.gson.Gson;public class Plus {    IServerCallback cback;    public Plus(IServerCallback cback){        this.cback = cback;    }    public void add(int num1,int num2){        try {            cback.setResult(num1+num2);        } catch (RemoteException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    private int num1;    private int num2;    public int getNum1() {        return num1;    }    public void setNum1(int num1) {        this.num1 = num1;    }    public int getNum2() {        return num2;    }    public void setNum2(int num2) {        this.num2 = num2;    }    public Plus(int num1, int num2) {        super();        this.num1 = num1;        this.num2 = num2;    }    public void getResult(String jsonString){        Plus plus = new Gson().fromJson(jsonString, Plus.class);        try {            cback.setTransferString(plus.num1 +"+"+plus.num2 + "="+plus.getNum1()+plus.getNum2());        } catch (RemoteException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

Client端的代码如下:

package com.example.aidl1;import com.example.aidl.IServer;import com.example.aidl.IServerCallback;import com.google.gson.Gson;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class MainActivity extends Activity {    Button btnBind;    TextView tvResult;    Intent server;    IServer mServer = null;    Button btnTransfer ;    Button btnTransfeString;    iServerCallImpl callback = new iServerCallImpl();    private ServiceConnection conn  = new ServiceConnection(){        @Override        public void onServiceConnected(ComponentName arg0, IBinder arg1) {            // TODO Auto-generated method stub            Log.i("123", "onServerConnected");            mServer = IServer.Stub.asInterface(arg1);            registerCallBack();        }        @Override        public void onServiceDisconnected(ComponentName arg0) {            // TODO Auto-generated method stub            ungisterCallBack();        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btnBind = (Button) findViewById(R.id.btn_bind);        tvResult = (TextView) findViewById(R.id.tv_result);        btnTransfer = (Button) findViewById(R.id.btn_transfer);        btnTransfeString = (Button) findViewById(R.id.btn_transferstring);        btnBind.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View arg0) {                // TODO Auto-generated method stub                server = new Intent("com.example.server");                bindService(server, conn, Context.BIND_AUTO_CREATE);            }        });        btnTransfer.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View arg0) {                // TODO Auto-generated method stub                if(mServer!=null){                    try {                        mServer.setAddNum(10, 22);                    } catch (RemoteException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }            }            }        });        btnTransfeString.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View arg0) {                // TODO Auto-generated method stub                Plus plsPlus = new Plus(30, 50);                String json = new Gson().toJson(plsPlus);                try {                    mServer.setString(json);                } catch (RemoteException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        });    }    private class iServerCallImpl extends IServerCallback.Stub{        @Override        public void setResult(int result) throws RemoteException {            // TODO Auto-generated method stub            if(tvResult != null){                tvResult.setText(""+result);            }        }        @Override        public void setTransferString(String jsonString) throws RemoteException {            // TODO Auto-generated method stub            if(tvResult != null){                tvResult.setText(""+jsonString);            }        }    }    private void registerCallBack(){        if(mServer == null){            return;        }        try {            mServer.registerServerCallBack(callback);        } catch (RemoteException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    private void ungisterCallBack(){        if(mServer == null){            return;        }        try {            mServer.unregisterServerCallBack(callback);        } catch (RemoteException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        return true;    }   }

Plus.java

package com.example.aidl1;import android.os.RemoteException;import com.example.aidl.IServerCallback;import com.google.gson.Gson;public class Plus {    private int num1;    private int num2;    public int getNum1() {        return num1;    }    public void setNum1(int num1) {        this.num1 = num1;    }    public int getNum2() {        return num2;    }    public void setNum2(int num2) {        this.num2 = num2;    }    public Plus(int num1, int num2) {        super();        this.num1 = num1;        this.num2 = num2;    }    IServerCallback cback;    public Plus(IServerCallback cback){        this.cback = cback;    }    public void add(int num1,int num2){        try {            cback.setResult(num1+num2);        } catch (RemoteException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public void getResult(String jsonString){        Plus plus = new Gson().fromJson(jsonString, Plus.class);        try {            cback.setTransferString(plus.num1 +"+"+plus.num2 + "="+plus.getNum1()+plus.getNum2());        } catch (RemoteException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

从以上我们可以看到:
使用json字符串取代了复杂的对象的序列化
使用CallBack回调将server处理的数值来进行回调给Client
注意:因为我这个是一个Client对应的一个Server端,但是在实际操作中,很多时候我们往往遇到多个Client绑定一个Server端,那么这个时候我们就会遇到多个CallBack,这个时候,可能我们的,每个CallBack需要回调不同的结果再调用给Client端。那么我就需要用到RemoteCallBack的广播机制,去轮询所有的CallBack,然后才能通知不同的Client
如:

  final int N = mCallbacks.beginBroadcast();            for (int i=0; i<N; i++) {                try {                       mCallbacks.getBroadcastItem(i).(方法);                 } catch (RemoteException e) {                    // The RemoteCallbackList will take care of removing                    // the dead object for us.                }            }            mCallbacks.finishBroadcast();

类似以上伪代码,这样就可以整体的向所有的Client进行回调了
注意:使用Json可以取代复杂的序列化过程

源码下载地址:源码地址

1 0
原创粉丝点击