Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid: Creating a new thread invokes onResume?
    primarykey
    data
    text
    <p>I guess this is a more generic question, but my Android program seems to call onResume in the main UI thread in between these two thread-creation-related function calls. This causes other invocations that I don't want to happen, and so far the only way around it that I've found is setting global flags (which I don't like, and is bad programming practice in my opinion). It looks rather like this:</p> <pre><code>mConnectThread = new ConnectThread(bd); mConnectThread.start(); </code></pre> <p>Somehow, in between these calls (which are made from the UI thread by a BluetoothCommHandler object), onResume gets called. If anyone could point me to a good source of when onResume and other activity lifecycle events are triggered, I would be much obliged. Further, I checked this: <a href="http://developer.android.com/reference/android/app/Activity.html" rel="nofollow">http://developer.android.com/reference/android/app/Activity.html</a>, and it didn't seem to have any hints that I could find.</p> <p>A last note - the onResume ALWAYS gets called in between those two commands getting called, and that makes me think it's not really a thread-switching issue.</p> <p>I've also just noticed that the onResume gets called as the pair of an onPause that gets called WAY earlier - still no idea why it happens precisely between these two function calls though.</p> <p><strong>EDIT:</strong> Code is included below.</p> <p>Invocation of the bluetooth handler object:</p> <pre><code>mBComm = new BluetoothCommHandler(this, mHandler); </code></pre> <p>The onResume function in the main UI thread (the <code>mNoRestartFlag</code> is so that this particular bit gets called only when I want it to. It's <strong>NOT</strong> the flag I'm referring to above - it handles another case that I'm not speaking about here):</p> <pre><code>@Override protected void onResume() { super.onResume(); mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists); Log.i(TAG, "OnResume called."); if(mBComm != null &amp;&amp; !mNoRestartFlag) { mBComm.start(); } } </code></pre> <p>Activity OptionsHandler (same as DeviceListActivity) declaration in the AndroidManifest (note that it's a Theme.Dialog styled activity, which pops on top of the UI thread, causing the onPause I've referred to above):</p> <pre><code>activity android:name=".OptionsHandler" android:label="@string/select_device" android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden" /&gt; </code></pre> <p>The actual connectThread gets created:</p> <pre><code>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(); } </code></pre> <p>The creation and running of the ConnectThread (the <code>mDontKill</code> flag <strong>IS</strong> the flag I am mentioning above that I use to bypass the onResume symptoms):</p> <pre><code>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); } </code></pre> <p>The actual start() function that causes the issues:</p> <pre><code>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 &amp;&amp; !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(); } } </code></pre> <p><strong>Legend:</strong> <code>mBS</code> is a member variable that is a BluetoothSocket and <code>mDB</code> is a member variable that is a BluetoothDevice.</p> <p><em>To summarize</em>, I create a BluetoothCommHandler object on the UI Thread, this tries to create a ConnectThread and then while calling the accept() command on a bluetooth socket, it fails because the cancel() function for the thread has been called (that simply has a try-catch that closes the socket). This cancel is called from the start() function that is listed above, that is called by the onResume function. The onResume is the complement of the onPause that is getting called because of a selector dialog appearing over the main UI activity. This onResume seems to always get called in between the first two lines of code that I mentioned pre-EDIT. I'm trying to figure out why it always happens exactly THERE, so that I can have an accept() occur without the socket being closed.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload