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

在  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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值