android Binder 實現異步回調

場景描述

此時有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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章