Android AIDL进程IPC通信 一次就好

来源:互联网 发布:js文件解压缩 编辑:程序博客网 时间:2024/05/17 22:42
1.什么是aidl:aidl是 Android Interface definition language的缩写,一看就明白,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口


为什么使用AIDL
一:两个进程之间使用AIDL进行通信:
二、由于Android对单个应用所使用的最大内存做了限制,为了加大一个应用可使用的内存,所以通过多进程来获取多份内存空间。

特点:
1.通过startservice开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了. 
调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在  
2.通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 , 
一旦调用者挂掉了.service也会跟着挂掉 .
问题:别人的程序不能给你提供接口调用,否则挂了怎么办?


AIDL主要是是bundle进行通信的!

像服务器那样的不需要运行,只要安装了就可以
我们客户端访问的时候,服务可能启动了和没启动
你都启动一下进行绑定,然后在……

主要实现步骤:(主要有三条,分别为AIDL、Service、和调用处(demo中为MainActivity))

能够在当前进程中MainActivity,运行另一个进程中开启的Service中实现的方法testMethod(),方法与最终效果如下:

AIDL的步骤
1.写一个IMYService.aidl文件,主要是定义接口,elipse 会自动在gen下面生成一个.同名的IMYService.java

aidl文件自动帮我们生成Proxy、Stub(抽象类)两个类

interface IMyService {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     */    String getValue();}

2.创建一个远程Service,在Service中创建一个类继承AIDL接口中的Stub类并实现Stub中的抽象方法,最后不要忘记在onBind中返回这个类的对象。

public class MyService extends Service{   public class MyServiceImpl extends IMyService.Stub   {      @Override      public String getValue() throws RemoteException      {         // TODO Auto-generated method stub         return "Android深度探索(卷1):HAL与驱动开发》";      }   }   @Override   public IBinder onBind(Intent intent)   {      return new MyServiceImpl();   }}

public interface IMyService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements server.aidl.peng.cx.com.aidlserver.IMyService

在OnBinder方法里面系统会自动将这个对象封装成IBinder对象,传递给他的调用者。

实例:桌面小组件控制音乐播放器:   Service里面还有一个类,继承gen生成的文件,实现里面全部的方法


4.清单文件里面配置一下IMYService

<application    android:allowBackup="true"    android:icon="@mipmap/ic_launcher"    android:label="@string/app_name"    android:supportsRtl="true"    android:theme="@style/AppTheme">    <activity android:name=".MainActivity">        <intent-filter>            <action android:name="android.intent.action.MAIN" />            <category android:name="android.intent.category.LAUNCHER" />        </intent-filter>    </activity>    <service android:name=".MyService" >        <intent-filter>            <action android:name="mobile.android.aidl.IMyService" />        </intent-filter>    </service>    </application>

调用者;client

在另外一个程序调用服务流程,在要调用的地方(笔者demo中就为MainActivity中)绑定该Service,将Service返回的Binder对象转换成AIDL接口所属的类型,接着直接调用AIDL的方法。
1.复制生成的文件,包名也必须一样


2.服务是否连接上了


private ServiceConnection serviceConnection = new ServiceConnection(){    @Override    public void onServiceConnected(ComponentName name, IBinder service)    {        myService = IMyService.Stub.asInterface(service);        btnInvokeAIDLService.setEnabled(true);    }    @Override    public void onServiceDisconnected(ComponentName name)    {        Toast.makeText(MainActivity.this, "޷�����", Toast.LENGTH_SHORT).show();        btnInvokeAIDLService.setEnabled(true);    }};
myService = IMyService.Stub.asInterface(service);
怎么获取到Service的实例,不是实例,是实现类=====数据就好办了


3.怎么启动和调用服务

启动的是Action,Service在清单文件中的配置
if(!bindService(new Intent("mobile.android.aidl.IMyService"), 
总结:

    调用者----调用远程service-----通过service实例调用接口的方法
    所以Service的作用:封装接口方法和AIDL的封装
    应用场景:有服务的地方,打电话,播放音乐的服务,和服务程序没什么很大关联,Service是中介,四大组件之一进程间的通信


原理解析:

1) Proxy

Proxy运行在客户端,它实现了IDownloadService接口,并且持有一个远程代理IBinder mRemote,mRemote不做任何业务逻辑处理,仅仅通过IBinder接口的transact()方法,把客户端的调用参数序列化后transact到远程服务器。

2) Stub

Stub运行在服务器端,继承自Binder,同样也实现了IDownloadService接口,它的核心逻辑在onTransact方法中:

Stub中另外一个比较重要的接口就是asInterface()接口

通过方法名字,我们大致可以猜出,它大概实现的功能,就是将一个IBinder对象转化为接口对象

private android.os.IBinder mRemote;  

每次调用接口的方法:getValue()【自己定义的】
都会执行_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getValue_data_reply, 0);



Connection没有连接,应该是OnBind不能返回为null;




服务相关:

1.service

2.用在什么场合,一般都有Service绑定在一起
3.Service 开机启动
3.Service生命周期
4.怎么停止Service
5.Service怎么和Activity进行通信和界面(1.语音项目2.车载记录仪)
最关键的是Service的生命周期和activity的不一样
6.AIDL进行数据传输的时候,数据有限,必须序列化
aidl中使用java类,需要实现Parcelable接口,并且在定义类相同包下面对类进行声明: 
7.列子:来去电,挂断电话Telephone
8.Service列子====UI秒表列子



Service的启动方式:

startService:如果传参,必须用startService。在onstartCommand里面有个Intent
bindService:不能传参,不执行OnStartCommand方法,执行onbind方法

Service 中的oncreate没有getIntent方法!只有onstartComand方法里面才有!

startService和BinderService启动的是时候,有参和没有参,connection
  startService主要是请求一个服务而已
但是如果还要回调和activty要有一些链接的话,就必须用到BinderService


源码地址:不知道为什么上传不了



   问题:

    Android Service与Activity之间通信的几种方式?

   1). 通过Binder对象,也就是AIDL的形式

   2).   通过broadcast(广播)的形式


0 0
原创粉丝点击