Android之AIDL实例讲解

AIDL在Android开发中用于进程间的通讯,举个例子,你有个程序A中用“张三”这个用户名正在登录,当你打开另一个程序B,想让“张三”这个用户自动登录,那你就需要获取程序A中“张三”用户名和密码。怎么做呢?这便用到了AIDL技术。

下面我们通过一个实例来实现上述应用场景,假设程序A我命名为AIDLServer,作为服务端;程序B我命名为AIDLClient,作为客户端。我们先来编写服务端:

第一步建立aidl文件,基础数据类型都可以;List、Map也可以,但其里面的内容也必须是java基础数据类型。

IAIDLServer.aidl:

package com.demo.aidlserver;

import com.demo.aidlserver.User;
interface IAIDLServer{
    String sayHello();
    User getUser();
}

如使用Object类型,需要该对象implement Parcelable接口,并且需要导入该接口包名+类名,且建立对象名.aidl文件声明该对象。

User.java:

package com.demo.aidlserver;

import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {

    private String userName;
    private String userPwd;
    private int age;

    public User(){}

    public User(Parcel parcel){
        userName = parcel.readString();
        userPwd = parcel.readString();
        age = parcel.readInt();
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPwd() {
        return userPwd;
    }

    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(userName);
        dest.writeString(userPwd);
        dest.writeInt(age);
    }

    public static final Parcelable.Creator<User> CREATOR = new Creator<User>(){

        @Override
        public User createFromParcel(Parcel source) {
            // TODO Auto-generated method stub
            return new User(source);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }

    };

}

User.aidl:

parcelable User;

做完上述操作后保存,会发现gen目录下会自动生成IAIDLServer.java,不必修改里面的内容!

第二步实现aidl接口,实际实现的接口是在 gen中自动生成的 IAIDLServer.java的抽象内部类Stub。建立AIDLServerService.java,继承Service,上面所说的IAIDLServer.java内包含一个抽象类stub,其继承了android.os.Binder,所以需要在onBind()方法中返回实现该类的对象。

package com.demo.aidlserver;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class AIDLServerService extends Service{

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private IAIDLServer.Stub mBinder = new IAIDLServer.Stub() {

        @Override
        public String sayHello() throws RemoteException {
            return "Hello World!!!";
        }

        @Override
        public User getUser() throws RemoteException {
            User user = new User();
            user.setUserName("zhangsan");
            user.setUserPwd("123456");
            user.setAge(25);
            return user;
        }
    };
}

第三步AndroidManifest.xml中配置对应service。

<service android:name="com.demo.aidlserver.AIDLServerService"  
                 android:process=":remote">  
            <intent-filter>  
                <action android:name="com.demo.aidlserver.IAIDLServer"></action>  
            </intent-filter>  
        </service>

至此,Server端编写完毕,目录结构如下图:
这里写图片描述
接下来我们来看下客户端的编写流程:
第一步是把服务器程序里关于要共享数据的接口的代码连同包一起拷过来,如下图:
这里写图片描述
第二步是当客户端调用bindService()方法就将绑定到指定Service

Intent service = new Intent("com.demo.aidlserver.IAIDLServer");  
                bindService(service, mConnection, BIND_AUTO_CREATE);

actoin的属性的采用aidl文件的类名+包名(与服务一致),之前需要在服务中设置相同的action属性,否则找不到服务。
第三步是客户端的OnServiceConnected()方法里调用IAIDLServerService.Stub.asInterface()将得到服务器端OnBind方法里IBinder类实例。

@Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mServer = IAIDLServer.Stub.asInterface(service);

            try {
                Toast.makeText(MainActivity.this, mServer.sayHello(), Toast.LENGTH_LONG).show();
                String mText = "";
                mText += "姓名:" + mServer.getUser().getUserName() + "\n";  
                mText += "密码:" + mServer.getUser().getUserPwd() + "\n";
                mText += "年龄:" + mServer.getUser().getAge();
                mTv.setText(mText);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

至此,全部逻辑完毕,客户端文档目录结构图如下:
这里写图片描述
运行Server,然后在运行Client,点击click按钮即可获得Server中的User对象并展示。以上例子仅起到抛砖引玉的作用,具体深层次的研究还需各位对源码进行研究。
源码下载地址

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值