Android:创建一个新线程调用onResume?

时间:2011-03-21 16:11:28

标签: java android multithreading application-lifecycle

我想这是一个更通用的问题,但我的Android程序似乎在这两个与线程创建相关的函数调用之间的主UI线程中调用onResume。这会导致我不希望发生的其他调用,到目前为止,我发现的唯一方法就是设置全局标志(我不喜欢这种标志,并且在我看来是糟糕的编程习惯)。看起来很像这样:

mConnectThread = new ConnectThread(bd);
mConnectThread.start();

不知何故,在这些调用之间(由BluetoothCommHandler对象从UI线程创建),onResume被调用。如果有人能指出我在onResume和其他活动生命周期事件被触发时的良好来源,我将非常感激。此外,我检查了这个:http://developer.android.com/reference/android/app/Activity.html,它似乎没有任何我能找到的提示。

最后一点 - 在调用这两个命令之间调用onResume ALWAYS,这让我觉得它不是一个真正的线程切换问题。

我还注意到onResume被调用为一对onPause,之前被称为WAY - 但仍然不知道为什么它恰好在这两个函数调用之间发生。

编辑:代码包含在下方。

调用蓝牙处理程序对象:

mBComm = new BluetoothCommHandler(this, mHandler);

主UI线程中的onResume函数(mNoRestartFlag是这样,只有当我想要它时才会调用这个特定的位。它是 NOT 我上面提到的标志 - 它处理另一个我不在这里谈论的案例):

@Override
protected void onResume() {
    super.onResume();

    mNfcAdapter.enableForegroundDispatch(this, mPendingIntent,
mFilters, mTechLists);

    Log.i(TAG, "OnResume called.");
    if(mBComm != null && !mNoRestartFlag) {
        mBComm.start();
    }
}
AndroidManifest中的 Activity OptionsHandler(与DeviceListActivity相同)声明(请注意,它是一个Theme.Dialog样式的活动,它弹出UI线程之上,导致我上面提到的onPause):

activity android:name=".OptionsHandler"
              android:label="@string/select_device"
              android:theme="@android:style/Theme.Dialog"
              android:configChanges="orientation|keyboardHidden" />

创建实际的connectThread:

public synchronized void connect(BluetoothDevice bd) {
    Log.i(TAG, "connect called from inside BluetoothCommHandler");

    if (mAcceptThread == null) {
        Log.i(TAG, "Creating an AcceptThread");
        mAcceptThread = new AcceptThread();
        mAcceptThread.start();
    }

    mConnectThread = new ConnectThread(bd);
    mConnectThread.start();
 }

创建和运行ConnectThread(mDontKill标志 IS 我上面提到的用于绕过onResume症状的标志):

public ConnectThread(BluetoothDevice bd) {
        Log.i(TAG, "created ConnectThread");
        mBD = bd;
        BluetoothSocket bs = null;

        try {
            bs = mBD.createInsecureRfcommSocketToServiceRecord(MY_UUID);                
        } catch (IOException e) {
            Log.i(TAG, "Could not create an RFCOMM socket!", e);
        }
        mBS = bs;
        if (mBS != null) Log.i(TAG, "BluetoothSocket acquired");
        else Log.i(TAG, "BluetoothSocket null!");

        mDontKillFlag = true;
    }

public void run() {
        Log.i(TAG, "BEGIN ConnectThread");
         // Always cancel discovery because it will slow down a connection
        mBluetoothAdapter.cancelDiscovery();

        mDontKillFlag = false;
        // Make a connection to the BluetoothSocket
        try {
            // This is a blocking call and will only return on a
            // successful connection or an exception
            mBS.connect();
            Log.i(TAG, "Connected to BluetoothDevice");
        } catch (IOException e) {
            Log.i(TAG, e.toString());
            // Close the socket
            try {
                mBS.close();
            } catch (IOException e2) {
                Log.i(TAG, "unable to close RFCOMM socket", e2);
            }
            Log.i(TAG, "About to call connectionFailed");
            connectionFailed();
            return;
        }

        // Reset the ConnectThread because we're done
        synchronized (BluetoothCommHandler.this) {
            mConnectThread = null;
        }

        // Start the connected thread
        connected(mBS, mBD);
    }

导致问题的实际start()函数:

public synchronized void start() {
    if (D) Log.i(TAG, "start called from inside BluetoothCommHandler");

    // Cancel any thread attempting to make a connection
    if (mConnectThread != null && !mDontKillFlag) 
    {mConnectThread.cancel(); mConnectThread = null;}

    // Cancel any thread currently running a connection
    if (mConnectedThread != null) 
    {mConnectedThread.cancel(); mConnectedThread = null;}

    if (mAcceptThread == null) {
        Log.i(TAG, "Creating an AcceptThread");
        mAcceptThread = new AcceptThread();
        mAcceptThread.start();
    }
}

图例: mBS是BluetoothSocket的成员变量,mDB是BluetoothDevice的成员变量。

总结一下,我在UI线程上创建一个BluetoothCommHandler对象,这会尝试创建一个ConnectThread,然后在蓝牙套接字上调用accept()命令时,它会因为cancel()而失败已经调用了线程的函数(它只是有一个关闭套接字的try-catch)。从上面列出的start()函数调用此取消,该函数由onResume函数调用。 onResume是因为在主UI活动上出现选择器对话框而被调用的onPause的补充。这个onResume似乎总是被我在编辑之前提到的前两行代码之间调用。我试图弄清楚为什么它总是恰好发生在那里,所以我可以在没有套接字被关闭的情况下发生一个accept()。

0 个答案:

没有答案