js css html

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

2022-11-21  本文已影响0人  安安_660c

一、绑定本地服务

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

上一篇下一篇

猜你喜欢

热点阅读