小言_互联网的博客

android Binder 实现异步回调

409人阅读  评论(0)

场景描述

此时有A、B两个进程,期望A与B实现进程间通信,并且在逻辑执行完毕后再A进程触发回调。期望过程如下:

  1. A进程 调用function()
  2. B进程 触发function()
  3. B进程 调用callback()
  4. A进程 触发callback()

执行效果

笔者demo中通过打log来记录方法的执行。
执行过程大致如下:

  1. 主进程 bindService
  2. remote进程 执行function(),在function中调用callback()。
  3. 主进程 执行callback()

代码

主要内容如下:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private IServer iServer;
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iServer = IServer.Stub.asInterface(service);
            System.out.println("onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            System.out.println("onServiceDisconnected");
        }
    };

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


        Button btnBind = findViewById(R.id.btn_bind);
        btnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //绑定service
                Intent intent = new Intent(MainActivity.this, RemoteTestService.class);
                bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
            }
        });

        Button btnTest = findViewById(R.id.btn_test);
        btnTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    //注册回调方法
                    iServer.setCallBack(new ICallBack.Stub() {
                        @Override
                        public void callback() throws RemoteException {
                            System.out.println("ICallBack callback()");
                        }
                    });
                    //触发远程调用
                    iServer.testFunction();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

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

RemoteTestService.java

/**
 * 进程间通信的service
 */
public class RemoteTestService extends Service {

    private final ServerBinder serverBinder = new ServerBinder();

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

}

ServerBinder.java

/**
 * IServer.aidl的实现
 */
public class ServerBinder extends IServer.Stub {

    @Override
    public void testFunction() throws RemoteException {
        System.out.println("IServer testFunction()");

        //调用callback
        int i = RemoteCallbackManager.getInstance().callbackList.beginBroadcast();
        while (i > 0) {
            i--;
            try {
                RemoteCallbackManager.getInstance().callbackList.getBroadcastItem(i).callback();
                RemoteCallbackManager.getInstance().callbackList.unregister(RemoteCallbackManager.getInstance().callbackList.getBroadcastItem(i));
            } catch (RemoteException e) {
                // The RemoteCallbackList will take care of removing
                // the dead object for us.
            }
        }
        RemoteCallbackManager.getInstance().callbackList.finishBroadcast();
    }

    @Override
    public void setCallBack(ICallBack callBack) throws RemoteException {
        //绑定callback
        RemoteCallbackManager.getInstance().callbackList.register(callBack);
    }
}

RemoteCallbackManager.java

/**
 * 用于存储RemoteCallbackList的单例
 */
public class RemoteCallbackManager {

    public RemoteCallbackList<ICallBack> callbackList;

    private RemoteCallbackManager() {
        callbackList = new RemoteCallbackList<>();
    }

    private static class Host {
        private static RemoteCallbackManager instance = new RemoteCallbackManager();
    }

    public static RemoteCallbackManager getInstance() {
        return Host.instance;
    }
}

IServer.aidl

interface IServer {
   void testFunction();
   void setCallBack(com.example.bindercallbacktest.ICallBack callback);
}

ICallBack.aidl

interface ICallBack {
    void callback();
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.bindercallbacktest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".RemoteTestService"
            android:process=":remote" />

    </application>

</manifest>

转载:https://blog.csdn.net/Double2hao/article/details/102529399
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场