浅析 - AIDL简单例子

尊重每个人的付出,转载请点这里 : http://blog.csdn.net/hanj456/article/details/52433718

传递基本数据类型

简单三步

Step 1

准备AIDL文件 ,注意:文件写完后需要 Sync Project一下!

package cn.test.aidlb;

interface IRemoteService {

    int getResult();

    void setText(String content);
}

Step 2

准备service ,要点:新建service文件后马上在清单文件中配置一下:
<service android:name=".MyService"
       android:process="com.test.action">
       <intent-filter>
           <action android:name="com.test.action"/>
           <category android:name="android.intent.category.DEFAULT"/>
       </intent-filter>
   </service>

服务端

public class MyService extends Service {
    private static final String TAG = "MyService";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("service onBind");
        return mBinder;
    }

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

        @Override
        public int getResult() throws RemoteException {
            int sum=5*4/2;
            return sum;
        }

        @Override
        public void setText(String content) throws RemoteException {
            Log.i(TAG, content+" 调用B应用的方法");
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("service onCreate");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("service onDestroy");
    }
}

Step 3

首先将service端应用中的aidl包复制到activity所在的应用中,在activity中进行绑定服务,注意:android 5.0以后 intent需要设置包名

客户单

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private IRemoteService mService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    /**
     * 点击按钮后绑定服务
     * @param view
     */
    public void bind(View view){
        Intent intent = new Intent();
        intent.setAction("com.test.action");
        intent.setPackage("cn.test.aidlb");
        bindService(intent,sc, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection sc = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = IRemoteService.Stub.asInterface(service);
            try {
                int result = mService.getResult();
                mService.setText("我在A应用 ");
                Log.i(TAG, "onServiceConnected: result="+result);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };


    /**
     * activity销毁时解绑服务
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (sc!=null){
            unbindService(sc);
        }
    }
}

传递对象

服务端简单6步

Step1

创建对象文件Person.java,实现Parcelable接口

public class Person implements Parcelable{

    private int age;
    private String name;


    protected Person(Parcel in) {
        age = in.readInt();
        name = in.readString();
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Person() {
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

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

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

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

    public void readFromParcel(Parcel dest) {
        age = dest.readInt();
        name = dest.readString();
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Step2

创建AIDL文件 Person.aidl ,声明对象为序列化

package com.xxx.xxxx;

parcelable Person;

注:parcelable第一个字母p为小写

Step3

创建AIDL接口文件 IPerson.aidl,声明传递数据需要的方法,这里需要重点说明的是数据流向的关键字声明
in ,out , inout 三者的用法和区别:简单点说就是当你的数据需要从Service端设置,Client端获取时使用out,
反之使用 in ,如果需要双向传递数据就使用 inout.

package com.test.myServer;

import com.test.myServer.Person;

interface IPerson {

    String inPerson(in Person p);
    String outPerson();
    String inoutPerson(inout Person p);
}

Step4

这一步需要在Model下的 gradle 文件中 android 标签下加上以下内容,否则完成第五步后编译会报找不到
Person对象的错误:

sourceSets {
        main {
            java.srcDirs = ['src/main/java', 'src/main/aidl']
        }
    }

Step5

新建一个service文件,要点就是实现返回我们自己定义的AIDL接口

public class AidlService extends Service {

    private MyBinder mBinder;

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


    private class MyBinder extends IPerson.Stub{
        @Override
        public String inPerson(Person p) throws RemoteException {
            String person = "age="+p.getAge()+",name="+p.getName();
            Log.i("test", "inPerson: "+person);
            return person;
        }

        @Override
        public String outPerson() throws RemoteException {
            Person p = new Person();
            p.setAge(22);
            p.setName("Tom");
            return p.toString() ;
        }

        @Override
        public String inoutPerson(Person p) throws RemoteException {
            Log.i("test", "inPerson: "+p.toString());
            return p.toString();
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mBinder = new MyBinder();
    }
}

Step6

在清单文件中声明创建的service文件,需要注意的是要加上action作为唯一的意图标记,最后将服务端创建的aidl文件及Person.java文件复制到客户端。

<service android:name=".AidlService">
            <intent-filter>
                <action android:name="com.test.myServer.action.AIDL_SERVICE"/>
            </intent-filter>
        </service>

再来看看客户端,这边就比较简单,重点是把服务端需要的文件复制过来之后需要clean一下project,如果在
(客户端)/build/generated/source/aidl/debug下出现service文件所在的包和aidl文件,那么恭喜你,下面
基本就没有什么难度了。

public class ComplexActivity extends AppCompatActivity{

    private TextView mTv_content;
    private EditText mEt_age;
    private EditText mEt_name;
    private IPerson mIPerson;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_complex);
        initView();
        bind();
    }

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mIPerson = IPerson.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mIPerson = null;
        }
    };

    private void bind() {
        Intent intent = new Intent();
        intent.setAction("com.test.myServer.action.AIDL_SERVICE2");
        intent.setPackage("com.test.myServer");
        bindService(intent,conn, Service.BIND_AUTO_CREATE);
        Log.i("test", "bind: 绑定服务");
    }

    private void initView() {
        mTv_content = (TextView) findViewById(R.id.tv_content);
        mEt_age = (EditText) findViewById(R.id.et_age);
        mEt_name = (EditText) findViewById(R.id.et_name);
    }

    /**
     * 调用aidl接口中的inPerson方法,该方法声明的数据流向是 in,
     * 表示由客户端设置数据,服务端可以接收客户端传过来的数据
     * @param v
     */
    public void setInfo(View v){
        String age = mEt_age.getText().toString().trim();
        String name = mEt_name.getText().toString().trim();
        try {
            if (!TextUtils.isEmpty(age)&&!TextUtils.isEmpty(name)){
                mIPerson.inPerson(new Person(Integer.parseInt(age),name));
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }

    /**
     * 调用aidl接口中的outPerson方法,该方法声明的数据流向是 out,
     * 表示数据流向是从服务端传输到客户端,所以在服务端中设置数据,
     * 在客户端中进行显示数据
     * @param v
     */
    public void showInfo(View v){
        try {
            String content = mIPerson.outPerson();
            mTv_content.setText(content);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }


    /**
     * 调用aidl接口中的inoutPerson方法,该方法声明的数据流向是 inout,
     * 表示数据是可以双向流动的,既可以在客户端设置数据从服务端取数据,
     * 也可以从服务端设置数据,在客户端取数据
     * @param v
     */
    public void showDoubleInfo(View v){
        String age = mEt_age.getText().toString().trim();
        String name = mEt_name.getText().toString().trim();
        try {
            if (!TextUtils.isEmpty(age)&&!TextUtils.isEmpty(name)){
                mIPerson.inoutPerson(new Person(Integer.parseInt(age),name));
                //String content = mIPerson.inoutPerson(); 
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值