• Android之IPC(aidl)


    IPC(Inter-Process Conmunication) 进程间通讯

    在同一进程中,各个组件进行通信是十分方便的,普通的函数调用就可以解决;但是,对于处于不同进程中的组件来说,要进行通信,就需要用到Android的IPC机制了。

    IBinder/Binder是Android远程对象的基本接口,它是Android用于提高IPC通信而设计的一套轻量级远程调用机制的核心部分。该接口描述了与一个远程对象进行通信的抽象协议。

    AIDL: Android interface definition language Android接口定义语言:专门用来解决进程之间的通信。

    1. 远程服务:运行在其他应用里面的服务
    2. 本地服务:运行在自己应用里面的服务
    3. 进程间通信 IPC
    4. aidl支持的类型:基本数据类型,String,CharSequence, List, Map, 自定义(实现Parcelable接口的)对象

    AIDL 实现步骤:

    1. 先把Iservice.java文件变为aidl文件,不要修饰符
    2. 会自动生成一个Stub类,实现IPC
    3. 我们定义的MyBinder类直接实现Stub类,Stub是继承Binder实现IService接口
    4. 想要保证应用程序的aidl文件是同一个,要求aidl文件所在的包名相同
    5. 通过Stub类的静态方法Stub.asinterface(IBinder obj)获取IService对象

    实现操作:

     Remote服务器端:

    记得在清单文件中注册服务,并设置action动作,以便在另一个应用中连接通信。

    // IService.aidl
    package com.example.lenovo.remoteservice;
    
    // Declare any non-default types here with import statements
    
    interface IService {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
    
         int callAddMethod(int a, int b);
    }
    public class MyRemoteService extends Service {
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new MyBinder();
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            return super.onUnbind(intent);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    
        public int  addMethod(int a, int b){
           return a+b;
        }
    
        class MyBinder extends IService.Stub{
            @Override
            public int callAddMethod(int a, int b) throws RemoteException {
                return addMethod(a, b);
            }
        }
    }

    Local客服端:

    public class MainActivity extends Activity {
        private Button button;
    
        IService iService;
        private MyConn conn;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            button = (Button) findViewById(R.id.button);
            conn = new MyConn();
            Intent intent = new Intent();
            intent.setAction("com.example.lenovo.remoteservice");
            bindService(intent, conn, BIND_AUTO_CREATE);
    
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        int res = iService.callAddMethod(3, 4); //远程服务计算3+4的运算
                        Toast.makeText(MainActivity.this, "由远程方法计算的结果为: 3+4=" + res, Toast.LENGTH_SHORT).show();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        
        private class MyConn implements ServiceConnection{
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                  iService  =  IService.Stub.asInterface(service);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            unbindService(conn);
        }
    }

    aidl的应用场景:支付宝  

    Messenger:

    实现IPC通信,底层也是使用了AIDL方式。和AIDL方式不同的是,Messenger方式是利用Handler形式处理,因此,它是线程安全的,这也表示它不支持并发处理;而AIDL方式是非线程安全的。支持并发处理。因此,我们使用AIDL处理的时候需要注意线程安全的问题。很多情况下,我们应用中不需要并发处理。因此,我们通常只需要使用Messenger方式。

    实现思想:

    在进程A中创建一个Message, 将这个Message对象通过Messenger.send(message)方法传递到进程B, send(message)方法是不可以对Message对象直接传递,需要使用Parcel对象进行编集;再将Parcelable对象传到进程B中,然后解集。再把Message对象添加到消息队列中,Handler会对其进行处理。

     实现步骤:

    1. 创建一个服务类继承Service
    2. 在服务中定义一个Handler对象
    3. 再声明定义一个Messenger对象: private Messenger messenger = new Messenger(handler);
    4. 在onBind()方法中返回一个IBinder对象: return messenger.getBinder();
    5. 在本地客户端中通过绑定服务获取返回的IBinder对象,进行send(message)操作
    6. 在远程服务端对发送的消息进行相应的处理
  • 相关阅读:
    Pthon3各平台的安装
    scrapy爬虫 简单入门
    自动定时打卡7.13
    centos7+python3+selenium+chrome
    在Ubuntu安装kubernetes
    在Ubuntu下安装Jenkins
    在Ubuntu安装Docker
    猫眼100 爬虫
    python 招聘数据分析
    mysql8.0.19忘记密码
  • 原文地址:https://www.cnblogs.com/denluoyia/p/5991105.html
Copyright © 2020-2023  润新知