Android之AIDL使用

AIDL是一个缩写,全称是Android Interface Definition Language,Android接口定义语言。设计这门语言的目的是为了实现进程间通信。因为两个进程无法直接通信,需要Android系统底层间接通信。

Android中三种通信方式和使用场景:

AIDL    IPC        多个应用程序     多线程

Binder    只有IPC    没有多线程    多个应用程序

Messenger    只有IPC 没有多线程

要学习AIDL之前,你肯定要学会两点:

1.关于Android中service相关的知识

2.关于Android中序列化的相关知识

AIDL传递的数据类型:

1.基本数据类型(除short外)

2.String,CharSequence

3.List,map

4.Parcelable

AIDL基本语法:

1.语法和java的接口相似

2.AIDL只支持方法,能定义静态成员

3.AIDL运行方法有任何类型的参数和返回值

4.除默认的类型外,均需要导包

首先创建一个和java同级的Folder;如图:

然后创建一个后缀为.aidl 的文件,如图:

*aidl的包名要和java下的包名要一致,aidl的文件名你可以自定义

一.传递基本数据

计算两个数的和,要在服务端实现方法,在客户端计算它们的和:

在服务端的aidl文件中:里面默认的方法你可以留下也可以删除;

// IMyAidlInterface.aidl
package com.example.myapplication;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
    int add(int num1, int num2);
}

然后接下来需要一个Service暴露一个接口给客户端,创建一个Service;


public class MyService extends Service {

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

   private IBinder iBinder=new IMyAidlInterface.Stub(){

       @Override
       public int add(int num1, int num2) throws RemoteException {
           Log.e("TAG", "收到了---------- "+num1+"--------"+num2);
           return num1 + num2;
       }
   };
}

然后在客户端,我是同一个项目里面创建一个Module,作为客户端,然后同样创建一个和服务端一样的和java同级的Floder和aidl文件,包名和类名要和服务端一致;

 

// IMyAidlInterface.aidl
package com.example.myapplication;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
    int add(int num1, int num2);
}

内容和服务端一样,你可以拷贝过来;然后创建一个Activity,和服务端的Service进行通信;

public class MainActivity extends Activity {

    @BindView(R.id.edit_num1)
    EditText editNum1;
    @BindView(R.id.edit_num2)
    EditText editNum2;
    @BindView(R.id.edit_result)
    EditText editResult;
    @BindView(R.id.btn)
    Button btn;
    @BindView(R.id.btn1)
    Button btn1;
    IMyAidlInterface iMyAidlInterface;
    private ServiceConnection myconn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            iMyAidlInterface = null;
        }
    };
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        bingServiceTest();
    }

    @OnClick(R.id.btn)
    public void onViewClicked() {
        int num1 = Integer.parseInt(editNum1.getText().toString());
        int num2 = Integer.parseInt(editNum2.getText().toString());
        try {
            int res = iMyAidlInterface.add(num1, num2);
            editResult.setText(res + "");
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }
   
    private void bingServiceTest() {
        Intent intent = new Intent();
        //第一个参数是你的包名,第二个是服务端的包名.你的Service名
        intent.setComponent(new ComponentName("com.test1221.lsntest0311", "com.test1221.lsntest0311.MyService"));
        bindService(intent, myconn, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy(); 
        unbindService(connection);
    }


}
activity_main的效果如下,布局我就不展示了,自己放按钮等其他的;

然后运行,首先你要启动你的服务端,然后在启动你的客户端,结果如下:

二.传递对象,自定义类型

步骤是一样,在服务端首先创建一个Person类实现序列化;

public class Person implements Parcelable{
    private String name;
    private int age;

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

    public Person(Parcel source) {
        this.name=source.readString();
        this.age=source.readInt();
    }

    public String getName() {
        return name;
    }

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

    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(name);
          dest.writeInt(age);

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

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

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

然后在aidl Floder下创建,如图:

// IMyAidlPerson.aidl
package com.test1221.lsntest0311;

// Declare any non-default types here with import statements
import com.test1221.lsntest0311.Person;

interface IMyAidlPerson {
      List<Person> add( in Person person);
}
// IMyAidlPerson.aidl
package com.test1221.lsntest0311;

parcelable Person;

然后在Service里面:


public class PersonService extends Service {
    private ArrayList<Person> persons;

    @Override
    public IBinder onBind(Intent intent) {
        persons=new ArrayList<Person>();
        return binder;
    }

    private Binder binder=new IMyAidlPerson.Stub(){

        @Override
        public List<Person> add(Person person) throws RemoteException {
            persons.add(person);
            return persons;
        }
    };
}

就下来是在客户端,复制过来就行;内容一样的;

 

也要把Person类复制过来,包名要一样;

然后在Activity里面实现:

package com.fjx.test1221.aidlclient;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;

import com.fjx.test1221.lsntest0311.IMyAidlInterface;
import com.fjx.test1221.lsntest0311.IMyAidlPerson;
import com.fjx.test1221.lsntest0311.Person;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends Activity {

    @BindView(R.id.edit_num1)
    EditText editNum1;
    @BindView(R.id.edit_num2)
    EditText editNum2;
    @BindView(R.id.edit_result)
    EditText editResult;
    @BindView(R.id.btn)
    Button btn;
    IMyAidlInterface iMyAidlInterface;
    IMyAidlPerson aidlPerson;
    @BindView(R.id.btn1)
    Button btn1;
   
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            aidlPerson=IMyAidlPerson.Stub.asInterface(service);
        }

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        bingServiceTest();
    }
  
    @OnClick(R.id.btn1)
    public void onViewClicked1() {
        try {
            List<Person> list= aidlPerson.add(new Person("张三",26));
            Log.e("list", list.toString() );
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    private void bingServiceTest() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.test1221.lsntest0311", "com.test1221.lsntest0311.PersonService"));
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }
   
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection );  
    }
}

 view视图就一个按钮,我就不展示了,运行:

 好了,基本就讲完了,自定义类型里面的 in  out  inout你们可以搜一下其他文章看看。

文章借鉴来自于https://www.cnblogs.com/BeyondAnyTime/p/3204119.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值