Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onCreate() after finish() in onStop()

I have an Android activity that calls finish() inside it's onStop() so when I switch to other activities (including the main menu), the activity will be shut down. Up this point, everything works as expected.

However, when I run the application again, (sometimes, not always) I notice the application runs using the same PID as the previous and it calls onCreate() again. I didn't see any call to onRestart() so I assume that onCreate() call is performed straight after onStop(), which is something that violates the activity lifecyce. When the app uses a new PID, I can understand why onCreate() is called, that's because this is the beginning of the activity.

Anyone knows why this happen?

A bit about the app I am developing: This is a Unity + Vuforia + Android application. I create a custom activity because I need to create a native UI on Android (instead of from Unity).

I found a similar issue reported into the Android project: http://code.google.com/p/android/issues/detail?id=15331 but I am not sure if the cause is the same or not.

update: From what I see from the log, after the finish() call, there is no call to onDestroy(). However, if the problem I mentioned happens (the activity is started using the same process), there is a call to onDestroy() at the beginning of activity.

update: Sorry for the late update. Here I show an excerpt of the logcat.

## First run

I/ActivityManager(  265): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=the.app/the.app.UnityAriusActivity bnds=[238,115][351,273] } from pid 423
I/ActivityManager(  265): Start proc the.app for activity the.app/the.app.UnityAriusActivity: pid=1686 uid=10013 gids={3003, 1006, 1015}
D/arius   ( 1686): UnityAriusActivity: onStart
D/arius   ( 1686): UnityAriusActivity: onResume

## Home button is pressed

I/ActivityManager(  265): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.sonyericsson.home/.HomeActivity } from pid 265
D/arius   ( 1686): UnityAriusActivity: onPause
D/arius   ( 1686): UnityAriusActivity: onStop

## Second run

I/ActivityManager(  265): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=the.app/the.app.UnityAriusActivity bnds=[238,115][351,273] } from pid 423

## Same process, onStart is called again

D/arius   ( 1686): UnityAriusActivity: onStart
D/arius   ( 1686): UnityAriusActivity: onResume
I/ActivityManager(  265): Displayed the.app/the.app.UnityAriusActivity: +500ms
D/Unity   ( 1686): Creating OpenGL ES 2.0 context (RGB16 565 16/0)
W/IInputConnectionWrapper(  423): showStatusIcon on inactive InputConnection
I/QCAR    ( 1686): onSurfaceCreated

## Strangely, there's an onDestroy here

D/arius   ( 1686): UnityAriusActivity: onDestroy

## Unity apparently kills the process from its onDestroy

I/Process ( 1686): Sending signal. PID: 1686 SIG: 9
I/ActivityManager(  265): Process the.app (pid 1686) has died.

The problem is that, there's an onDestroy() after onStart() on the second run. My activity is basically a subclass of Vuforia/QCAR activity which is also a subclass of activity from Unity. So, inside my onDestroy(), I make a call to the superclass' (super.onDestroy()) and also the same for the other methods that I override.

If I looked at the Unity and Vuforia/QCAR Android library (I was curious so I decompiled them -- yeah this may be not right), inside Unity's onDestroy(), Unity tries to kill its own process (which is the application process).

Process.killProcess(Process.myPid());

So, when this happens, my app just shut down again. If the second run uses different process, that strange onDestroy() does not happen.

I have also tried the noHistory approach. But the same thing still happens :( When the second run uses the same process, a late onDestroy() will appear and then the process is kill by Unity.

like image 386
fajran Avatar asked Jun 19 '12 10:06

fajran


2 Answers

You are making an understandable, but critical error in assuming that a new activity must run in a new process. That is not actually the case on android - you can have the onCreate() of a new activity instance occur in a process that has been kept around after hosting an earlier activity instance.

This can make anything that is static with respect to a process (especially, though not exclusively in native code) puzzlingly unreliable.

Because the activity that is being started is a new one, it will not receive an onRestart() - that would happen only if you were restarting an existing activity.

like image 187
Chris Stratton Avatar answered Oct 19 '22 05:10

Chris Stratton


Why don't you just set noHistory="true" on the activity's manifest entry? Then you don't have to worry about manually finishing the activity in onStop().

Search for noHistory in http://developer.android.com/guide/topics/manifest/activity-element.html

Or, alternatively, set the FLAG_ACTIVITY_NO_HISTORY in your startActivity() intent. http://developer.android.com/reference/android/content/Intent.html#FLAG%5FACTIVITY%5FNO%5FHISTORY

like image 44
Josh Avatar answered Oct 19 '22 03:10

Josh