I would like to finish() a paused activity that is underneath a transparent activity.
I have an activity, called activity A. Two things can happen while activity A is active;
we can launch (a transparent) Activity B
we can receive an asynchronous callback to finish activity A.
These two actions happen very close to each other. The code looks like this
public class ActivityA extends Activity
{
public class DataHandler implements ContentLoader.OnDataListener
{
@Override
public void onData(Cursor data)
{
_binder.bind(data);
}
}
//If this callback is executed while Activity A is paused, it will not go into onStop until it the activity above it is finished
private class LoaderCallbacks extends ContentLoader.LoaderCallbacks
{
public LoaderCallbacks(ContentLoader loader)
{
super(loader);
}
@Override
public void onLoadFinished(
Loader<Cursor> loader,
Cursor cursor)
{
if (cursor == null || cursor.getCount() <= 0)
{
Log.d("Eric", "* ON FINISH *");
finish();
finishagain();
return;
}
super.onLoadFinished(loader, cursor);
}
}
}
Inside of a listfragment shown by this activity there is a mechanism for launching Activity B
public class FragmentA extends ListFragment
{
//Some fragment functions here...
@Override
public void onListItemClick(
ListView list,
View view,
int position,
long id)
{
Intent intent = new Intent();
intent.setAction(Intent.LAUNCH_ACTIVITY_B);
getActivity().sendBroadcast(intent)
}
}
My problem is when the callback to finish activity A is called AFTER activity B is launched, then Activity A is not being finished immediately. It remains in the paused state until Activity B is finished, and then both finish. This is a race condition, and I've confirmed this by trying to finish again, while in the paused state, using a simple waiting thread. All the finish calls are performed on the main thread, as expected.
private void finishagain()
{
Handler handler = new Handler();
int LOCK_HOME_DELAY = 5000;
handler.postDelayed(new Runnable()
{
public void run()
{
if (notfinished){
Log.d("Eric", "*************** FINISH AGAIN ****************");
finish(); //Does nothing while the activity is paused
}
else{
Log.d("Eric", "* Times up do nothing *");
}
}
}, LOCK_HOME_DELAY);
}
Here are my logs (some package names may be redacted)
10-10 18:23:05.168 74-98/system_process I/ActivityManager: Displayed somepackage/com.eric.activity.A: +894ms
10-10 18:23:07.135 74-98/system_process I/ActivityManager: Displayed somepackage/com.eric.activity.B: +343ms
10-10 18:23:07.102 547-547/somepackage D/Eric: * Times up do nothign *
10-10 18:23:07.231 547-547/somepackage D/Eric: * ON FINISH *
10-10 18:23:08.220 547-547/com.eric.Status D/Eric: * Times up do nothign *
10-10 18:23:08.305 547-547/com.eric.Status D/Eric: * Times up do nothign *
10-10 18:23:12.305 547-547/com.eric.Status D/Eric: *************** FINISH AGAIN ****************
10-10 18:23:12.305 74-668/system_process W/ActivityManager: Finishing task with all activities already finished
10-10 18:23:12.305 74-668/system_process W/ActivityManager: Duplicate finish request for ActivityRecord{3627639c u0 somepackage/com.eric.activity.A t2292 f}
(Notice the timestamps - I call finish at :07 seconds, and it doesnt finish. finishAgain() calls finish again at :12 seconds, and it appears to close here, but I've seen it finish later too. Also note the "duplicate finish request" - to me it looks like the finish was queued or something).
How can I get Activity A to finish when it is paused underneath the transparent Activity B?
TO be honest, I'm surprised this is an issue; I thought activities on the backstack should be readily killeable, but perhaps not those in the onPause state? I haven't been able to find documentation on this, perhaps someone knows the relevant doc/code?
EDIT see my answer