Android AIDL进程IPC通信 一次就好

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值