美文网首页js css html
Bind跨进程通信之绑定本地服务和远程服务AIDL

Bind跨进程通信之绑定本地服务和远程服务AIDL

作者: 安安_660c | 来源:发表于2022-11-21 17:35 被阅读0次

    一、绑定本地服务

    1.1在AndroidManifest.xml文件中声明服务:
    <service android:name".TestLocalService">
        <intent-filter>
        <action android:name = "maureen.intent.action.BIND_LOCAL_SERVICE"/>
        </intent-filter>
    </service>
    
    1.2TestLocalService服务端代码
    public class TestLocalService extends Service{
        
        
        private final String TAG = TestLocalService.class.getSimpleName();
        private IBinder mServiceBinder = new TestLocalServiceBinder();
        
        public class TestLocalServiceBinder extends Binder{
                public TestLocalService getService(){
                    return TestLocalService.this;
                }
        }
        
           public void testFunc() {
            Log.d(TAG,"testFunc");
            Log.d(TAG, Log.getStackTraceString(new Throwable()));
    
        
        @Override
        public void onCreate(){
            super.onCreate();
        }
        
        @Nullable
        @Override
        public IBinder onBind(Intent intent){
            //Server 返回一个IBind
            return mServiceBinder;
        }
        
        @Override
        public boolean onUnbind(Intent intent){
            return super.onUnbind(intent);
        }
        
        @Override
        public void onDestroy(){
            super.onDestroy();
        }
    }
    
    1.3TestBindServiceActivity(Activity客户端代码)

    点击按钮绑定Service
    绑定成功后调用TestLocalService里的testFunc方法
    点击back键解绑服务

    public class TestBindServiceActivity extends Activity{
        
        private static final Strin TAG = TestBindServiceActivity.class.getSimpleName();
        private static final String ACTION_BIND_LOCAL_SERVICE = "maureen.intent.action.BIND_LOCAL_SERVICE";
        private Button mBindLocalServiceBtn;
        private static ServiceConnection mLocalConnection;
        private static TestLocalService mLocalService = null;
        
        private static class TestLocalConnection implements ServiceConnection{
            @Override
            public void onServiceConnected(ComponentName componentName,IBinder iBinder){
                //注:这里获取的IBinder就是服务中返回的IBinder
                Log.d(TAG,"onServiceVonnected:iBinder="+iBinder);
                mLocalService = ((TestLocalService.TestLocalServiceBinder)iBinder).getService();
                mLocalService.testFunc();
            }
            
            @Override
            public void onServiceDisconnected(ComponentName componentName){
                mLocalService = null;
            }
        }
        
        private static class ButtonClickListener implements View.onClickListener{
            private WeakReference<TestBindServiceActivity> mActivity;
            public ButtonClickListener(TestBindServiceAcitvity activity){
                mActivity = new WeakReference<>(activity);
            }
            @Override
            public void onClick(View view){
                switch(view.getId()){
                    case R.id.bind_local_service:
                        Intent localIntent = new Intetn();
                        localIntent.setPackage("com.example.maureen.mytestbindservice";
                        localIntent.setAction(ACTION_BIND_LOCAL_SERVICE);
                        mActivity.get().bindService(localIntent,mLocalConnection,BIND_AUTO_CREATE);
                        break;
                    default:
                        break;
                }       
         }
    }                
                                               
            @Override
            protected void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                log.d(TAG,"onCreate");
                setContentView(R.layout.activity_test_bind_service);
                mLocalConnection = new TestLocalConnection();
                mBindLocalServiceBtn = findViewById(R.id.bind_local_serice);
                mBindLocalServiceBtn.setOnCLickListener(new ButtonClickListener(this));
            }
                                               
            @Override
            protected void onDestroy(){
                super.onDestroy();
                Log.d(TAG,"onDestroy");
                unbindService(mLocalConnection);
            }
    } 
    

    值得注意:在本地服务使用时,服务端onBind函数返回mBinder和客户端onServiceConnected中的iBinder参数是相同的

    二、绑定远程服务

    2.1AndroidManifest.xml中声明Service,并指定Service运行的进程:
    <service android:name=".TestRemoteService"
        android:process=":remote">
        <intent-filter>
        <action android:name="maureen.intent.action.BIN_REMOTE_SERVICE"/>
        </intent-filter>
    </service>
    
    2.2编写AIDL文件 IRemoteServiceAidlInterface.aidl
    interface IRemoteServiceAidlInterface{
        //此处写需要进行通信的方法
        void testFunc1();
        void testFunc2();
    }
    
    2.3点击编译,会在gen目录下生成AIDL文件
    public interface IRemoteServiceAidlInterface extends android.os.IInterface {
        /** Local-side IPC implementation stub class. */
        public static abstract class Stub extends android.os.Binder implements com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface {
            private static final java.lang.String DESCRIPTOR = "com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface";
            
            /** Construct the stub at attach it to the interface. */
            public Stub() {
                this.attachInterface(this, DESCRIPTOR);
            }
            
            /**
             * Cast an IBinder object into an com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface interface,
             * generating a proxy if needed.
             */
            public static com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface asInterface(android.os.IBinder obj) {
                if ((obj==null)) {
                    return null;
                }
                ndroid.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
                if (((iin!=null)&&(iin instanceof com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface))) {
                    return ((com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface)iin);
                }
                return new com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface.Stub.Proxy(obj);
            }
            
            @Override 
            public android.os.IBinder asBinder() {
                return this;
            }
            
            @Override 
            public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
                java.lang.String descriptor = DESCRIPTOR;
                switch (code) {
                    case INTERFACE_TRANSACTION: {
                        reply.writeString(descriptor);
                        return true;
                    }
                    
                    case TRANSACTION_testFunc1: {
                        data.enforceInterface(descriptor);
                        this.testFunc1();
                        reply.writeNoException();
                        return true;
                    }
                    
                    case TRANSACTION_testFunc2: {
                        data.enforceInterface(descriptor);
                        this.testFunc2();
                        reply.writeNoException();
                        return true;
                    }
                    
                    default: {
                        return super.onTransact(code, data, reply, flags);
                    }
                }
            }
            
            private static class Proxy implements com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface {
                private android.os.IBinder mRemote;
                Proxy(android.os.IBinder remote) {
                    mRemote = remote;
                }
                
                @Override 
                public android.os.IBinder asBinder() {
                    return mRemote;
                }
                
                public java.lang.String getInterfaceDescriptor() {
                    return DESCRIPTOR;
                }
                
                /**
                 * Demonstrates some basic types that you can use as parameters
                 * and return values in AIDL.
                 */
                @Override 
                public void testFunc1() throws android.os.RemoteException {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        mRemote.transact(Stub.TRANSACTION_testFunc1, _data, _reply, 0);
                        _reply.readException();
                    } finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                }
                
                @Override 
                public void testFunc2() throws android.os.RemoteException {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        mRemote.transact(Stub.TRANSACTION_testFunc2, _data, _reply, 0);
                        _reply.readException();
                    } finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                }
            }
            
            static final int TRANSACTION_testFunc1 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
            static final int TRANSACTION_testFunc2 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
        }
        
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        public void testFunc1() throws android.os.RemoteException;
        public void testFunc2() throws android.os.RemoteException;
    }
    
    2.4TestRemoteService服务端代码
    public class TestRemoteService extends Service {
        private final String TAG = TestRemoteService.class.getSimpleName();
        private IBinder mRemoteBinder = new RemoteServiceImpl(this);
        
        private static class RemoteServiceImpl extends IRemoteServiceAidlInterface.Stub{
            private final String TAG = RemoteServiceImpl.class.getSimpleName();
            private WeakReference<TestRemoteService> mRemoteService;
            public RemoteServiceImpl(TestRemoteService service){
                mRemoteService = new WeakReference<>(service);
            }
            
            @Override
            public void testFunc1(){
                Log.d(TAG,"testFunc1";
                Log.d(TAG,Log.getStackTraceString(new Throwable()));
                      mRemoteService.get().testMyFunc1();
                      }
            @Override
            public void testFunc2(){
                Log.d(TAG,"testFunc2");
                mRemoteService.get().testMyFunc2();
            @Override
            public void onCreate(){
                super.onCreate();
                Log.d(TAG,"onCreate");
            }
            
            @Nullable
            @Override
            public IBinder onBind(Intent intent){
                Log.d(TAG,"onBind:mRemoteBinder="+mRemoteBinder);
                return mRemoteBinder;
            }
                
            @Override
            public boolean onUnbind(Intent intent){
                Log.d(TAG,"onUnbind");
                return super.onUnbind(intent);
            }
                
            @Override
            public void onDestroy(){
                super.onDestroy();
                Log.d(TAG,"onDestroy");
            }
     }
    
    2.5TestBindServiceActivity(Activity为客户端代码)

    点击按钮,绑定远程服务
    服务绑定成功后,调用AIDL中声明的testFunc1和testFunc2方法
    点击back,解绑服务

    public class TestBindServiceActivity extends Activity{
        private static final String TAG = TestBindServiceActivity.class.getSmpleName();
        private static final String ACTION_BIND_REMOTE_SERVICE = "maureen.intent.action.BIND_REMOTE_SERVICE";
        private Button mBindRemoteServiceBtn;
        private static ServiceConnection mRemoteConnection;
        
        private static class TestRemoteConection implements ServiceConnection{
            @Override
            publi void onServiceConnected(ComponentName componentName,IBinder iBinder){
                Log.d(TAG,"onServiceConnected:iBinder="+iBinder);
                //找出已完成注册的服务
                IRemoteServiceAidlInterface remoteService = IRemoteServiceAidlInterface.Stub.asInterface(iBinder);
                try{
                    //此处即可调用服务端方法
                    remoteService.testFunc1();
                    remoteService,testFunc2();
                }catch(RemoteException e){
                    e.printStackTrace();
                }
            }
            
            @Override
            public void onServiceDisconnected(CompomemtName componentName){
            }
        }
        
        private static class ButtonClickListener implements View.OnClickListener{
            private WeakReference<TestBindServiceActivity>mActivity;
            public ButonClickListener(TesBindServicaActivity activity){
                mAvtivity = new WeakReference<>(activity);
            }
            @Override
            public void onClick(View view){
                switch(view.getId()){
                    case R.id.bind_remote_service:
                        Intent remoteIntent = new Intent();
                        //设置意图的包名
                        remoteIntent.setPackage("com.xxx.xxx.包名");
                        //设置意图的服务名
                        remoteIntent.setAction(ACTION_BIND_REMOTE_SERVICE);
                        //绑定服务参数:意图(包括服务所在包名和清单文件中注册的服务子标签action名)
                        mActivity.get().bindService(remoteIntent,mRemoteConnection,BIND_AUTO_CREATE
                        break;
                    default:
                        break;
                     }
             }
    }
    

    同样值得注意的是:在远程绑定过程中,服务端onBind返回的mRemoteBinder是一个Binder服务端对象;而,客户端TestReomoteServiceConnection的onServiceConnected函数中iBinder其实是Binder的代理对象。

    来自:https://www.yuque.com/yutao-pdqwk/pt44ra/gcsxdr

    相关文章

      网友评论

        本文标题:Bind跨进程通信之绑定本地服务和远程服务AIDL

        本文链接:https://www.haomeiwen.com/subject/kesnxdtx.html