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 mCallbacks      = new RemoteCallbackList();      @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; itry {                       mCallbacks.getBroadcastItem(i).(方法);                 } catch (RemoteException e) {                    // The RemoteCallbackList will take care of removing                    // the dead object for us.                }            }            mCallbacks.finishBroadcast();

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

源码下载地址:源码地址

更多相关文章

  1. Android Service总结04 之被绑定的服务 -- Bound Service
  2. android将线程绑定在指定CPU
  3. listView显示对象以及access any RESTFull service that uses JS
  4. 基于Android DataBinding的InverseBindingMethod改进SeekBar双向
  5. Android应用程序绑定服务(bindService)的过程
  6. android 面向对象数据库 db40使用demo
  7. Android中的strings文件中字符串的拼接
  8. Android定义字符串数组资源并在程序中使用
  9. 33、Android 中子fragment控制父对象改变布局

随机推荐

  1. android:adjustViewBounds 、android:cro
  2. Android的AlertDialog详解
  3. Android输入框自动提示
  4. Compile android NDK without Eclipse
  5. android activity设置全屏以及Android获
  6. Android系统启动之Zygote
  7. Android学习笔记3之基本组件API
  8. Android客户端、服务端、数据库开发流程
  9. 解决android下创建avd设备不成功.txt
  10. android--RelativeLayout布局的一些理解