Java Android:创建一个新线程调用onResume?
我想这是一个更一般的问题,但我的Android程序似乎在这两个线程创建相关函数调用之间的主UI线程中调用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
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();
}
}