aidl ( 一 ) activity获取后台service数据

来源:互联网 发布:mac打字不显示候选框 编辑:程序博客网 时间:2024/05/27 06:50

在  service和activity通信这篇文章的基础上,我们再来学习aidl。

aidl是android跨进程通信的常用方法

AIDL对Java类型的支持如下:

1.AIDL支持Java原始数据类型。

2.AIDL支持String和CharSequence。

3.AIDL支持传递其他AIDL接口,但你引用的每个AIDL接口都需要一个import语句,即使位于同一个包中。

4.AIDL支持传递实现了android.os.Parcelable接口的复杂类型,同样在引用这些类型时也需要import语句。(Parcelable接口告诉Android运行时在封送(marshalling)和解封送(unmarshalling)过程中实现如何序列化和反序列化对象,你可以很容易联想到java.io.Serializable接口。有些朋友可能会有疑问,两种接口功能确实类似,但为什么Android不用内置的Java序列化机制,而偏偏要搞一套新东西呢?这是因为Android团队认为Java中的序列化太慢,难以满足Android的进程间通信需求,所以他们构建了Parcelable解决方案。Parcelable要求显示序列化类的成员,但最终序列化对象的速度将快很多。另外要注意的是,Android提供了两种机制来将数据传递给另一个进程,第一种是使用Intent将数据束(Bundle)传递给活动,第二种也就是Parcelable传递给服务。这两种机制不可互换,不要混淆。也就是说,Parcelable无法传递给活动,只能用作AIDL定义的一部分)。

5.AIDL支持java.util.List和java.util.Map,但是有一些限制。集合中项的允许数据类型包括Java原始类型、String、CharSequence或是android.os.Parcelable。无需为List和Map提供import语句,但需要为Parcelable提供import语句。

6.非原始类型中,除了String和CharSequence以外,其余均需要一个方向指示符。方向指示符包括in、out、和inout。in表示由客户端设置,out表示由服务端设置,inout表示客户端和服务端都设置了该值。默认类型其实隐含了一个默认指示符in

参考自http://blog.csdn.net/liuhe688/article/details/6409708


注意事项

1、oneway关键字在跨进程调用的时候使得调用不阻塞,直接返回。在同一个进程内,oneway没有任何意义。

2、aidl文件可以引用aidl文件,但不能引用java文件。所以有时候我们想要在进程间传输某个对象,比如BaseData,首先要BaseData实现parceble,写一个java文件,然后在同样的目录下写个同名aidl文件,并注明parceble BaseData作为定义,然后其他aidl文件才能引用BaseData,可参考http://blog.csdn.net/dangnianmingyue_gg/article/details/48197293 内的PayClass。


例子

activity获取service数据关键连接点是onServiceConnected

首先写服务端的app:  AidlServer

这里我们创建一个Service类MyService,在MyService中放1个计时器

 public void onCreate() {        super.onCreate();        String TAG="";        LogFish.d("onCreate process name " + SystemUtil.getCurProcessName(MyService.this));        Log.i(TAG, "Service is Created");        thread = new Thread(new Runnable() {            @Override            public void run() {                // 每间隔0.1秒count加1 ,直到quit为true                while (!quit) {                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    count++;                }            }        });        thread.start();    }

编写aidl接口,getCount用来获取service的数据,complexCal用来做复杂计算,注意这里是跨进程的

interface IMyAidlInterface {int getCount();double complexCal(String str,int t);}

service中的binder重写aidl接口方法

    IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {        @Override        public int getCount() throws RemoteException {            return count;        }        @Override        public double complexCal(String str, int t) throws RemoteException {            int  ret=str.hashCode()+t;            return ret*0.3;        }    };

manifest中的MyService配置如下

        <service            android:name=".MyService"            android:process="com.myservice">            <intent-filter>                <action android:name="com.example.servicetest.MyAIDLService" />            </intent-filter>        </service>


文件目录如下:




再编写客户端app:AidlClient

首先在同样目录下,放一模一样的aidl文件

再编写activity文件,代码如下

public class MainActivity extends Activity implements View.OnClickListener {    private Button bindService;    private Button unbindService;    private IMyAidlInterface myAIDLInterface;    private ServiceConnection connection = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {        }        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            LogFish.d("process name"+ SystemUtil.getCurProcessName(MainActivity.this));            myAIDLInterface = IMyAidlInterface.Stub.asInterface(service);            try {                int cnt = myAIDLInterface.getCount();                double db = myAIDLInterface.complexCal("hello world",6);                LogFish.d("result is " + cnt);                LogFish.d( "complexCal value " + db);            } catch (RemoteException e) {                e.printStackTrace();            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        bindService = (Button) findViewById(R.id.bind_service);        unbindService = (Button) findViewById(R.id.unbind_service);        Button bv = (Button) findViewById(R.id.get_num);        bv.setOnClickListener(this);        bindService.setOnClickListener(this);        unbindService.setOnClickListener(this);        Intent intent = new Intent("com.example.servicetest.MyAIDLService");        startService(intent);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.bind_service:                Intent intent = new Intent("com.example.servicetest.MyAIDLService");                boolean b= bindService(intent, connection, Service.BIND_AUTO_CREATE);                LogFish.d("bind result "+b);                break;            case R.id.unbind_service://                Intent unbindIntent = new Intent(this, com.aidl.server.MyService.class);                unbindService(connection);                LogFish.d("unbind ");                break;            default:                break;        }    }}


Ok,代码编写完毕,先安装AidlServer,再运行AidlClient

结果如下:

05-13 19:35:07.246    1734-1734/com.aidl.client D/LogFish﹕ result is 41
05-13 19:35:07.246    1734-1734/com.aidl.client D/LogFish﹕ complexCal value is 5.382318174E8


result是指service启动到bind之间的时间,complexCal value是AidlServer计算出来的结果,AidlClient提供参数


用到module:AidlServer和AidlClient



0 0
原创粉丝点击