Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/187.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android:创建一个新线程调用onResume?_Java_Android_Multithreading_Application Lifecycle - Fatal编程技术网

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

Java Android:创建一个新线程调用onResume?,java,android,multithreading,application-lifecycle,Java,Android,Multithreading,Application Lifecycle,我想这是一个更一般的问题,但我的Android程序似乎在这两个线程创建相关函数调用之间的主UI线程中调用onResume。这会导致我不希望发生的其他调用,到目前为止,我发现唯一的解决方法是设置全局标志(我不喜欢,我认为这是糟糕的编程实践)。看起来很像这样: mConnectThread = new ConnectThread(bd); mConnectThread.start(); 不知何故,在这些调用之间(由BluetoothCommHandler对象从UI线程发出),会调用onResume

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

mConnectThread = new ConnectThread(bd);
mConnectThread.start();
不知何故,在这些调用之间(由BluetoothCommHandler对象从UI线程发出),会调用onResume。如果有人能告诉我onResume和其他活动生命周期事件的触发时间,我将不胜感激。此外,我检查了这个:,它似乎没有任何提示,我可以找到

最后一个注意事项是,onResume总是在调用这两个命令之间被调用,这让我觉得这不是真正的线程切换问题

我还注意到onResume被调用为onPause的一对,而onPause被调用的时间比onPause早——但我仍然不知道为什么它正好发生在这两个函数调用之间

编辑:代码包含在下面

调用bluetooth处理程序对象:

mBComm = new BluetoothCommHandler(this, mHandler);
主UI线程中的onResume函数(即
mNoRestartFlag
)是这样的:只有在我需要时才会调用这个特定的位。它不是我上面提到的标志,它处理的是另一种情况,我这里没有提到):

AndroidManifest中的Activity OptionHandler(与DeviceListActivity相同)声明(请注意,它是一个主题.对话框样式的活动,弹出在UI线程的顶部,导致上面提到的onPause):

将创建实际的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的创建和运行(我上面提到的用于绕过onResume症状的标志是
mDontKill
标志):

导致问题的实际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,然后在bluetooth套接字上调用accept()命令时,它失败了,因为该线程的cancel()函数已被调用(它只是有一个关闭套接字的try catch)。此取消从上面列出的start()函数调用,该函数由onResume函数调用。onResume是onPause的补充,因为在主UI活动上出现选择器对话框,所以会调用onPause。这个onResume似乎总是在我提到的前两行代码之间调用。我正试图弄清楚为什么它总是在那里发生,这样我就可以在不关闭套接字的情况下产生accept()。

我可以,这只是一项将其剔除以使其更具可读性的任务。我试着把它作为TL;请尽可能地说。我将把它精简一点,过一会儿再发布。您能确认您的两个方法实际上是从UIThread调用的吗?如果它与onResume交错,那么我猜您的线程创建代码不在UIThread上。不能从同一线程中同时调用两个方法。在启动另一个线程时,使用调试器或打印Thread.currentThread.getName()。如果该值为“main”,则该值位于UIThread上,并且您假设安卓在这两次调用之间调用onResume是错误的。此外,如果您的
活动正在恢复,则它必须在某个点暂停。您真的希望它在代码执行期间暂停吗?如果没有,您应该找出暂停发生的原因,这可能会让您对问题有更多的了解。
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();
 }
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);
    }
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();
    }
}