在AsyncTask的'doInBackground'方法中等待(不忙)BroadcastReceiver Intent

时间:2018-01-02 19:54:32

标签: android events android-asynctask future

目前我正在尝试等待AsyncTask中的BroadcastReceiver接收的事件。

原因是我的蓝牙抽象只通过广播/意图发出事件。

private static AsyncTask<Void, Void, Boolean> mConnectTask;
private static ManualResetEvent mConnectEvent = new ManualResetEvent(false);
private static Object mLockConnectTask;

private static final BroadcastReceiver mCustomReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, final Intent intent) {
        final String action = intent.getAction();
        if (ASNYCACTION_CUSTOM.equals(action)) {

            // first try:
            synchronized (mLockConnectTask) {
                mConnectTask.notify();
            }

            // second try:
            mConnectEvent.set();

        }
        // ...
    }
}

private class ConnectToSensorTask extends AsyncTask<Void, Void, Boolean> {

    @Override
    protected Boolean doInBackground(Void... params) {
        mConnectEvent.reset();
        mLockConnectTask = new Object();

        // start async BT operation
        doAsyncBluetoothOperation();

        try {                       // wait for result
            // first try
            synchronized (mLockConnectTask) {
                wait();             // wait for ever
            }

            // second try
            mConnectEvent.waitOne(5000);    // wait for 5 seconds

        } catch (InterruptedException e) {
            Log.e("ConnectToSensorTask", "error - wait was interrupted.");
            return false;
        }
        return true;
    }
}

我的目标是为用户提供这样的界面

// interface method to get future to wait for outside
public AsyncTask<Void, Void, Boolean> connectAsync() {
    mConnectTask = new ConnectToSensorTask()
            .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    return mConnectTask;
}

...以这种方式使用它:

// connect to the sensor
mActivity.startProgressBar(R.string.message_connecting);
AsyncTask<Void, Void, Boolean> retConnect =
    BluetoothManager.getInstance().connectAsync();
try {
    Boolean isConnected = retConnect.get(PakkcheckManager.TimeoutSec, TimeUnit.SECONDS);
    mActivity.stopProgressBar();
    if(isConnected) {
        /// @todo PHIL connect here -> move code from MainFragment.onConnectionStateChanged
        mActivity.showMessageToast("CONNECTED YEAH - TODO REMOVE ME!");
    }
} catch(Exception e) {
    mActivity.stopProgressBar();
    mActivity.showMessageToast(R.string.error_unable_to_connect_to_sensor);
}

第一次尝试时会抛出异常: “java.lang.IllegalMonitorStateException:对象在wait()之前未被线程锁定” 我以为我会通过使用'mLockConnectTask'对象来同步它。 第二次尝试失败,因为应用程序等待5秒并在我的AsyncTask-wait方法之后而不是在/同时执行连接过程。

在AsyncTask内部等待BroadcastReceiver事件的最佳方法是什么?或者也许事件是一种更优雅的方式来实现'代码中的用户'的未来行为。

非常感谢您的帮助!

0 个答案:

没有答案