知识点-----AIDL(一)简单的aidl实现

AIDL是什么

AIDL(Android Interface Definition Language)是Android系统自定义的接口描述语言。可以用来实现进程间的通讯。

AIDL 支持的数据类型

共 4 种:

  1. Java 的基本数据类型
  2. List 和 Map 
    • 元素必须是 AIDL 支持的数据类型
    • Server 端具体的类里则必须是 ArrayList 或者 HashMap
  3. 其他 AIDL 生成的接口
  4. 实现 Parcelable 的实体

aidl实现步骤(案例一:简单的add)

        此次的demo,服务端也进行了调试,如果服务端调通了启动服务与调用方法,客户端启动服务和调用方法可直接复制过去。

服务端


1、创建项目:创建DemoAidlService项目(跟正常一样)
2、创建aidl文件

        在app(Android预览目录下)上右键 New -> AIDL -> AIDL File。此时自动创建aidl文件夹,并在aidl文件夹下创建跟DemoAidlService包名一样的路径,且创建aidl结尾的文件,
点击build后,发现build文件夹下自动生成debug文件夹下的aidl编译文件
3、添加aidl里的抽象方法:在aidl文件下添加方法(如add(in int x, in int y)

interface IAddAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    int add(in int x, in int y);
}

4、 创建服务:创建自定义服务AddService继承自Service,在生命周期onBind()中返回值返回 aidl对象mBinder,mBinder = InAddAidlInterface.Stub(){ 可重写抽象方法,并实现逻辑 }

public class AddService extends Service {


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

    IAddAidlInterface.Stub mBinder = new IAddAidlInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public int add(int x, int y) throws RemoteException {
            return x + y;//具体的实现逻辑
        }
    };

}

5、启动服务:启动服务时要用绑定式启动bindService,bindService(intent, mConn, Context.BIND_AUTO_CREATE),
关键是第二个mConn参数,mConn  = ServiceConnection(){ 默认两个抽象方法,在连接成功方法onServiceConnected中赋值aidl对象mService = IAddAidlInterface.Stub.asInterface(service) }
注意要asInterface,不然会报错。

public class MainActivity extends AppCompatActivity {

    private IAddAidlInterface mService;

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

        aboutService();

        findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int x = Integer.parseInt(((EditText) findViewById(R.id.et_add_x)).getText().toString());
                int y = Integer.parseInt(((EditText) findViewById(R.id.et_add_y)).getText().toString());
                try {
                    Log.d("baibai", "服务端 相加结果:" + mService.add(x, y));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

            }
        });

    }

    ServiceConnection mConn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("baibai", "服务端:连接 Service 成功");
            mService = IAddAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    private void aboutService() {
        Intent intent = new Intent(this, AddService.class);
        bindService(intent, mConn, Context.BIND_AUTO_CREATE);
    }


}

6、调用方法:实际调用mService的里的方法。

客户端


1、创建项目:创建DemoAidlClient项目(跟正常一样)
2、创建aidl文件(但是跟服务端创建的方式)


        不能右键New -> ……,因为如果这么创建会创建跟DemoAidlClient的包名是一样的,而我们需要的是跟服务端的包名一样,所以要自己手动创建跟服务端一样的包名路径,并把服务端的aidl复制到改包名下,build一下,客户端项目就可以引用到服务端aidl文件的抽象方法。
3、启动服务

扫描二维码关注公众号,回复: 4868322 查看本文章
public class MainActivity extends AppCompatActivity {

    private IAddAidlInterface mService;

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

        aboutService();

        findViewById(R.id.btn_add_client).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int x = Integer.parseInt(((EditText) findViewById(R.id.et_add_client_x)).getText().toString());
                int y = Integer.parseInt(((EditText) findViewById(R.id.et_add_client_y)).getText().toString());
                try {
                    Log.d("baibai", "客户端 相加结果:" + mService.add(x, y));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

            }
        });


    }

    private void aboutService() {
        Intent intent = new Intent();
        intent.setAction("bai.bai.bai.aidl.service_add");//5.0出现以后必须使用显示启动,不然会报错(加了下一行代码可解决这个问题)
        intent.setPackage("bai.bai.bai.demoaidlservice");//加了这行代码,就可以解决5.0版本后隐式启动服务报错的问题
        Log.d("baibai", "aboutService");
        bindService(intent, mConn, Context.BIND_AUTO_CREATE);
    }

    ServiceConnection mConn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("baibai", "客户端:连接 Service 成功");
            mService = IAddAidlInterface.Stub.asInterface(service);
        }

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

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

启动服务时要用绑定式启动bindService,bindService(intent, mConn, Context.BIND_AUTO_CREATE),
    第一个参数initent:intent里没有参数,要intent.setAction(过滤条件),即隐式调用,所以要在服务端的清单文件里给service添加acton,以便客户端使用
        ps:a、要在onDestory()方法里解除绑定,不然会报错。
            b、绑定的时候,必须有Intent.setPackage(服务器的包名),不然会报错(5.0后必须使用显示启动服务,添加这一行代码可解决这一报错问题)。
            c、只有在连接成功的时候才会调用onServiceConnected()方法,此时mBinder才不为空,类型转换的时候最好用IAddService.Stub.asInterface()方法,不要直接强制转换。
    第二个参数mConn:mConn  = ServiceConnection(){ 默认两个抽象方法,在连接成功方法onServiceConnected中赋值aidl对象mService = IAddAidlInterface.Stub.asInterface(service) }
        注意要asInterface,不然会报错。
4、调用方法:实际调用mService的里的方法。

参考git代码:服务端:https://github.com/baiyun1234/DemoAidlService

                     客户端:https://github.com/baiyun1234/DemoAidlClient

参考网址:https://blog.csdn.net/guanhang89/article/details/51386404

猜你喜欢

转载自blog.csdn.net/qq_36968707/article/details/86016046