Android Studio Service AIDL 详解

来源:互联网 发布:通讯录软件哪个好 编辑:程序博客网 时间:2024/06/05 10:57
  • 转载请注明出处:http://www.jianshu.com/p/0145b9d938e4

公司产品之前IM这块存在很多问题,消息到达率低,加上协议上有些问题,丢消息频繁,所以需要重构IM,AIDL不能解决以上问题。好吧!那AIDL可以解决什么问题?什么是AIDL?

什么是AIDL?

AIDL Android Interface definition language的缩写,它是一种Android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口

AIDL可以解决什么问题?

  • 可以实现多个应用程序共享同一个Service的功能,比如:IM服务可以提供给多个APP使用,先在推送基本都是采取这种方案
  • 可以跨进程调用服务里的方法

Android Studio AIDL 实战

大部分文章介绍都是在eclipse下介绍的,现在 Android Studio 作为开发工具比较普及了,所以我在Android Studio 下介绍(其实区别不大)。

言归正传,我们需要使用Android Studio实现一个远程Service,并且建立AIDL进行通信。

搭建了简单的Service框架

1.继承Service

package name.quanke.aidldemo;import android.app.Service;import android.content.Intent;import android.os.IBinder;/** * * Created by http://quanke.name on 16/7/23. */public class PushService extends Service {    public PushService() {    }    @Override    public IBinder onBind(Intent intent) {        return new LibHandler();    }    @Override    public boolean onUnbind(Intent intent) {        return super.onUnbind(intent);    }}

2.在AndroidManifest.xml里注册

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"          package="name.quanke.aidldemo">    <application            android:allowBackup="true"            android:icon="@mipmap/ic_launcher"            android:label="@string/app_name"            android:name=".App"            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=".PushService"                android:enabled="true"                android:process=":push"                android:exported="true">        </service>    </application></manifest>

建立AIDL

1.创建AIDL文件夹

创建AIDL文件夹
2.创建AIDL文件

创建AIDL文件
3.编写AIDL文件
// IHandler.aidlpackage name.quanke.aidldemo;// Declare any non-default types here with import statementsinterface IHandler {    void connect();}
4.AIDL文件 生成接口

AIDL文件 生成接口

生成后的样子


AIDL文件 生成后的样子
5.编写客户端 ServiceConnection
package name.quanke.aidldemo;import android.app.Application;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;/** * Created by quanke on 16/7/23. */public class PushManager {    private static final String TAG = "PushManager.class";    private IHandler iHandler;    private static PushManager ourInstance = new PushManager();    public static PushManager getInstance() {        return ourInstance;    }    private PushManager() {    }    public void init(Application app){        Intent binderIntent = new Intent(app,PushService.class);        app.bindService(binderIntent, serviceConnection, Context.BIND_AUTO_CREATE);    }    public void connect(){        try {            //通过AIDL远程调用            Log.d(TAG,"++start Remote++");            iHandler.connect();        } catch (RemoteException e) {            e.printStackTrace();        }    }    private ServiceConnection serviceConnection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            iHandler = IHandler.Stub.asInterface(service);            //连接成功调动        }        @Override        public void onServiceDisconnected(ComponentName name) {            //断开连接调用        }    };}
6.编写服务端实现connect方法
package name.quanke.aidldemo;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;/** * * Created by quanke on 16/7/23. */public class LibHandler extends IHandler.Stub{    @Override    public void connect() throws RemoteException {        Log.d("","connect()");    }    @Override    public IBinder asBinder() {        return null;    }}

以上实现了简单的连接,接下来我们实现传递自定义类型

传递自定义的类型

AIDL默认支持的类型包括Java基本类型(int、long、boolean等),和(String、List、Map、CharSequence),如果要传递自定义的类型需要实现android.os.Parcelable接口。自己写了一个实体类public class Message implements Parcelable。

package name.quanke.aidldemo.model;import android.os.Parcel;import android.os.Parcelable;/** *  * Created by quanke on 16/7/23. */public class Message implements Parcelable {    private long id;    private String content;    public long getId() {        return id;    }    public void setId(long id) {        this.id = id;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }    @Override    public String toString() {        return "Message{" +                "id=" + id +                ", content='" + content + '\'' +                '}';    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeLong(this.id);        dest.writeString(this.content);    }    public Message() {    }    protected Message(Parcel in) {        this.id = in.readLong();        this.content = in.readString();    }    public static final Creator<Message> CREATOR = new Creator<Message>() {        @Override        public Message createFromParcel(Parcel source) {            return new Message(source);        }        @Override        public Message[] newArray(int size) {            return new Message[size];        }    };}

修改IHandler

// IHandler.aidlpackage name.quanke.aidldemo;// Declare any non-default types here with import statementsimport name.quanke.aidldemo.model.Message;interface IHandler {    void connect();    void sendMessage(Message message);}

编译项目,报错

/Users/quanke/Dev/android/src/AIDLDemo/app/src/main/aidl/name/quanke/aidldemo/IHandler.aidlError:(6) couldn't find import for class name.quanke.aidldemo.model.MessageError:Execution failed for task ':app:compileDebugAidl'.> java.lang.RuntimeException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/quanke/Dev/android/tools/android-sdks/build-tools/23.0.3/aidl'' finished with non-zero exit value 1Information:BUILD FAILED

因为自定义类型不仅要定义实现android.os.Parcelable接口的类,还得为该实现类定义一个aidl文件,如下:


自定义类aidl文件
// IHandler.aidlpackage name.quanke.aidldemo.model;// Declare any non-default types here with import statementsimport name.quanke.aidldemo.model.Message;parcelable Message ;

切记 自定类型aidl文件名字、路径需要和自定义类名字、路径保持一致,

编译项目,还是报错

parameter 1: 'Message message' can be an out parameter, so you must declare it as in, out or inout.

AIDL不是 Java。它是真的很接近,但它不是 Java。

Java 参数没有方向的概念,AIDL 参数有方向,参数可以从客户端传到服务端,再返回来。

如果sendMessage方法的message参数是纯粹的输入参数--这意味着是从客户端到服务器的数据,你需要在AIDL声明:

void sendMessage(in Message message);

如果sendMessage方法的message参数是纯粹的输出-这意味着它的数据是通过从服务器到客户端,使用:

void sendMessage(out Message message);

如果sendMessage方法的message参数是输入也是输出-客户端的值在服务可能会修改,使用:

void sendMessage(inout Message message);

总结

Android Studio Service AIDL 详解 就到这里,现在应该可以使用AIDL实现想要的功能了,实现简答的AIDL很简单,主要是在自定义类型的时候,有几个坑注意就好。

源码地址: https://github.com/quanke/AIDLDemo.git

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 中国银行e贷逾期怎么办 招商银行e分期逾期怎么办 保单贷款还不了怎么办 离婚时按揭房怎么办 按揭房子不要了怎么办? 征信有问题怎么办房贷 夫妻一方不做房贷共还人怎么办 给你花逾期一年怎么办 文件夹密码忘记了怎么办 网址被qq拦截怎么办 手机qq邮箱中毒怎么办 邮箱附件带病毒怎么办? 打开了病毒附件怎么办? qq邮箱被拦截怎么办 邮件地址已被注册怎么办 信用卡欠款怎么办房贷 贷款还不起了怎么办 装修贷款无抵押怎么办 黑户买房做贷款怎么办 易分期无法还款怎么办 工行晚还款一天怎么办 手机银行网页打不开怎么办 顺丰分拣错误怎么办 超市生意越来越差怎么办 收到逾期催收函怎么办 手机贷逾期了怎么办 临额到期还不上怎么办 信用卡不想用了怎么办 授信时间到了怎么办 餐饮吃到苍蝇怎么办 商户二级处罚了怎么办 立刷蓝牙连不上怎么办 传奇3骑不了怎么办 房子说话有回音怎么办 老师声音哑了怎么办 人流后还有残留怎么办 人流后有残留物怎么办 模拟人生3外星人怎么办 模拟人生爸妈死孩子怎么办? 模拟人生3怎么办生日 圆通单号查不到怎么办