首页 > 代码库 > RemoteService与AIDL学习总结

RemoteService与AIDL学习总结

      最近公司内部组织的一个ANdroid四大组件的培训,由于自己是菜鸟,考试时被老师的一个问题忽悠住了,甚是丢人,估计过两天会被人事总监请喝茶。问题是Remote Service的生命周期是什么,我这一抬眼啊,就直接哆嗦了,什么?Remote是什么东东,RemoteService又是什么东东,其实大概知道就是那个什么AIDL的破玩意儿,之前还写过Demo,准确的说是copy别人的Demo,唉唉。。。所以说还是要自己动手翘翘才能容易理解啊,在大庭广众之下回答不上来,那是相当的没面子啊。事后想想这真是个简单的问题,Local Service,Remote Service不都是Service吗,只怪自己胆小,紧张之余把这个都忘了。话不多说,进入自己的yy当中,完全自己理解,如有错误,敬请谅解啊。

   1.最起码知道AIDL全称是什么吧,Android Interface Describe Language,不知道单词对不对,反正就是这个意思。

   2.要知道他是干嘛用的吧!进程间通信,就是两个不同进程间通信,就像QQ斗地主和QQ之间进行什么授权,我感觉应该就是用的这个,第一次登录斗地主的时候是要用户名和密码的,如果你装了QQ,那他就直接和QQ之间进行了通信,并且读取了QQ的帐号信息,然后登录斗地主,不知道腾讯的大牛是不是这么做的。

   3.我理解的步骤是:利用intent开启远程的Service,然后远程的Service就会启动,并且返回一个Ibinder,我就当他是个大包裹,按了包裹发射器,远程的邮局就向我发射大包裹,导弹里就携带了我需要的东西,美女、钞票,美哉。就是这个Service是另一个进程当中的,所以和我通信,是需要废一番周折的,如果是本地service,也就是同一个进程当中的话,我就直接伸手把美女抱住不就得了。

  4.话说AIDL能处理的还真不是美女,钞票啊,他能处理的数据包括JAVA基本数据类型,还有list,map啦,还有就是实现了Parceble接口的实例化对象,这个很好嘛,基本够用了。

   接下来就看看代码怎么实现吧:

(1)  间两个工程,Cilent和Server,在两个工程中建相同的一个包,注意!!!包名一定要完全相同,再在包下建立一个完全相同aidl文件,

package com.neil.aidl;interface ICallBack{  void giveCallBack(String parm);}

 好了,这是Client的ICallack.aidl,那么Server中的也得有一个和这个一模一样的文件,文件里就定义了一个接口,当然可以是多个接口,想几个就几个,返回值和参数跟是上面4所说的啦。定义好这个爱的了文件,那么在Android工程的gen目录下会自动生成一个JAVA类文件,长什么样子,自己去看就知道了,等他生成了java类以后,我们在客户端服务端就可用他们了,

(2)先来个简单的,进程间传个int吧,

先看服务端代码实现:

public class RemoteService extends Service{        private  int count=100;    @Override    public void onCreate() {        // TODO Auto-generated method stub        super.onCreate();        Toast.makeText(getApplicationContext(), "onCrearte", Toast.LENGTH_SHORT).show();    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        // TODO Auto-generated method stub        Toast.makeText(getApplicationContext(), "onStartCommand", Toast.LENGTH_SHORT).show();        return super.onStartCommand(intent, flags, startId);    }    @Override    public IBinder onBind(Intent intent) {        // TODO Auto-generated method stub        System.out.println("remote onBind "+countservice);        Toast.makeText(getApplicationContext(), "onbind", Toast.LENGTH_SHORT).show();        return countservice;    }    CountService.Stub countservice=new CountService.Stub() {                @Override        public int getCount() throws RemoteException {return count;        }    };

话说这里的就是一个Service的继承类,里边的生命周期一目了然,客户点bindService之后,这个service自然会先调用onCreate()方法了,随后就调用了onBind()方法,这个方法返回的是一个什么咧,看看,就是一个CountService的内部类Stub的对象,这个可以在gen下的文件中找到,他继承之binder,所以Service通过onind()方法返回给客户端的是一个Binder对象,而且这个Binder对象还实现了你在aidl文件中定义的那个接口,这下,好办了,你想得到什么,统统放在这个Stub实例中就OK了,当客户端地到之后,就可以取出里边返回的数据

  且看客户端是怎么得到这个Binder的

  public void bindRemoteService(){      Intent intent=new Intent();      intent.setAction(BIND_ACTION);      bindService(intent, mConnection, BIND_AUTO_CREATE);  }

这里便就是bindService了,看看里边的参数,第一个就是标志你要开启目标服务的的那个intent对象,第二个就是一个实现了ServiceConnection接口的对象,看看这个ServiceConnection对象

class CountServiceConnection implements ServiceConnection{    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        // TODO Auto-generated method stub        mCountService=CountService.Stub.asInterface(service);        showToast("connected");    }        @Override    public void onServiceDisconnected(ComponentName name) {        mCountService=null;        showToast("disconnected");    }        };

看见没,上面讲到的那个Binder对象就是在这里跑到客户端来的 mCountService=CountService.Stub.asInterface(service);

从这个mountService对象里就能得到在服务端放进去的数据。话说这就是AIDL进行跨进程通信的方法

话说还可以实现双方相互通信,客户端也可以想服务端传输数据,这时候就无所谓Client和Server。具体见Demo了。

http://download.csdn.net/detail/qmc0000/7938223

 

RemoteService与AIDL学习总结