Android Question How to handle "Killing previous instance (Main)"

Arf

Well-Known Member
Licensed User
Longtime User
I'm starting a new thread on this, as I am now more clear on the problem I was having and this thread title is much more apt.

The historical thread is here: https://www.b4x.com/android/forum/posts/493849/
https://www.b4x.com/android/forum/posts/493849/
I now realise that when starting an app that is in the background by clicking the app icon, SOMETIMES the last activity is simply resumed, but other times the OS thinks that it's starting a second instance, and kills the first instance. When this happens, I get "Killing previous instance (Main)" in the log window, and I run into problems.

The problems:
The re-created Main activity runs, then if I click on an icon to enter another activity (one that was active in the session prior to going into the background and me clicking the app icon to return to it), then that activity does start up, but totally misbehaves. For example if I click the back button to return to the Main activity, this fails. So I think something has gone wrong with the stack, control is trying to go from my activity back to the OTHER main (that the OS killed).

I have no idea how to handle this.
I thought if I could somehow detect (in main) that the previous instance has been killed, maybe I could somehow destroy the instances of the other paused activities, so they'll be newly created.
Or somehow end this new activity and revert back to the old one before it gets killed.
 

Arf

Well-Known Member
Licensed User
Longtime User
OK done.
Run 'ArfTest'. On the main screen, click the PATIENTS button.
On the screen that comes up (patients list), click the BACK button (just to show that the back button works, and takes you back to the main screen).
Now click PATIENTS again. When you have the patients screen in front of you this time, press HOME to return to desktop.
Now press the app icon. Main screen will load, and if you get a Killling Previous Isntance (Main) log, you will see the following problem:
Click on PATIENTS, when the screen appears, click the BACK button. Eveything goes wrong.
 

Attachments

  • ArfTest.zip
    304.6 KB · Views: 262
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
And I'm seeeing the problem on a 2013 nexus 7 with android 6.0.1.
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
If anyone runs my zipped project above, please let me know if the problem manifests itself.
Yesterday morning it was doing "Killling Previous Instance (Main)" every run in RELEASE for about an hour, then doing the same in DEBUG. Then it stopped doing it and behaved normally for a few debug sessions, I went back to release and it did it again, then back to debug and it did it every time.
So I am not sure what causes the frequency of "Killling Previous Instance (Main)", but it seems to occur far more often than not on my device.
Thanks.
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
I've tried adding a starter service, same thing happens. Really stuck with this, we are basically finished testing the app for first release and this is the last major issue I need to sort so keen to fix it!
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
Hi Erel,
Thanks for looking at it. I'm confused though. Where to put Activity_Keypress? I already have that function in my Patients activity. I added the "StartActivity(Main) to that to see what happens, and Activity_Keypress never gets hit.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
I still don't understand how that code relates to the problem I am having.
The problem is that my other activity modules are trying to return to an instance of main that doesn't exist because Android killed it and restarted Main.

I need to find out why Android is killing main and prevent it from doing so, or if that's not possible, find a way to detect and deal with the "Killing previous instance of main" condition and deal with it in a way my app doesn't crash.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
They will return to the new instance with the code I posted.

BTW, I forgot to finish the current activity in the previous code:
B4X:
Sub Activity_KeyPress (KeyCode As Int) As Boolean 'Return True to consume the event
   If KeyCode = KeyCodes.KEYCODE_BACK Then
     StartActivity(Main)
     Activity.Finish
     Return True
   End If
   Return False
End Sub
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
OK I'll try again (have to rush to dentist now).
When I ran in debug a moment ago, Activity_Keypress wasn't getting hit when I click the back button in the Patients activity after the 'go to background, click on icon to bring to foreground' step, and the app was freezing as before.
So it seems inter activity control is all in a funk by that stage already.
 
Last edited:
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
I've done some digging, and this link describes my exact situation:
http://stackoverflow.com/a/23220151
I can confirm this because if I click BACK when the main activity loads after the 'Killing Instance(Main)" occurs, control returns to the Patients activity correctly.
I tried to implement his solution by adding the following in my main's Activity_Create:
B4X:
#If JAVA
   if (!isTaskRoot()
  && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
  && getIntent().getAction() != null
  && getIntent().getAction().equals(Intent.ACTION_MAIN)) {

  finish();
  return;
  }
   #End If
But that won't compile, this sort of Intent stuff is a bit beyond me. So basically I think the answer I'm looking for is, is there a way to B4A-ize that code block above?
 
Last edited:
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
Ok, so I added "SetActivityAttribute(main, android:launchMode, "singleInstance")" to the manifest and it seems to have stopped the "Killing Instance (Main)" thing from occurring now. I also added a check for the last running activity in main's Activity_Resume and start the correct activity if it's paused, everything seems to be behaving itself now.

If anyone does know how I can implement the code block in my post above, please still do say, as I would prefer do handle this issue that way rather than the way I'm doing it now.

Thanks.
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
Would this:
B4X:
Dim r As Reflector
    r.Target = Activity.GetStartingIntent
    If r.RunMethod2("hasCategory", "android.intent.CATEGORY_LAUNCHER", "java.lang.string") Then
        If r.RunMethod2("getAction", "android.action.ACTION_MAIN", "java.lang.string") Then
            Activity.Finish
        End If
    End If

be the same as this?
B4X:
#If JAVA
   if (!isTaskRoot()
  && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
  && getIntent().getAction() != null
  && getIntent().getAction().equals(Intent.ACTION_MAIN)) {

  finish();
  return;
  }
   #End If

I think it looks roughly rightish, but I don't know how to convert the "!isTaskRoot()" bit. Haven't tried it yet.
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
Hi Erel,
I tried it but it's not working for me in my test sequence, the code never gets hit:

Start app first time from icon
click Patients icon
Press Android HOME button (app goes to background, Activity_Keypress is not hit, maybe because its a soft key)
Start app from icon (Killing Instance (Main))
Click Patients
Click Back (Activity_Keypress not hit as stack is compromised).
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It does work here. I've modified Activity_KeyPress in the Patients activity to:
B4X:
Sub Activity_KeyPress (KeyCode As Int) As Boolean
   If EditingPatient = True Or AddingPatient = True Then Return True
   If KeyCode = KeyCodes.KEYCODE_BACK Then
     If dobView.IsVisible Then
       dobView.btnCancel_Click 'emulate a click on Cancel button
     Else
       StartActivity(Main)
       Activity.Finish
     End If
     Return True
   End If
   Return False
End Sub
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
I just tried again, copying and pasting that function, but no luck.
Does that function get hit when you press the HOME button on your device?
I have never found a way to intercept a HOME button press on this Nexus 7.
 
Upvote 0
Top