I am running into problems where if a user navigates through several child activities without returning to the MainActivity in between, when they press the back button it closes to the Android Home screen. I never call finish() on my MainActivity, it doesn't happen consistently, and not from the same screens. It happens when I have gone through many different Activities without returning to the MainActivity.
I'm assuming that the system is terminating the Activity while its in the background, but I'm not sure. Is there anyway to ensure that my parent activity doesn't get terminated?
I did not create the project. I'm aware that the navigation structure he used isn't right, but as of right now I'm not in the position to fix it.
Please do not tell me to do things a different way. I am asking only if there is a way to keep a particular activity from being terminated by the system.
While it's not possible to stop your activity from being destroyed, you can check if there's no activities in the backstack, and restart your MainActivity when the back button is pressed in this particular case.
You could try to put a handler in it that doesn't do anything besides giving itself another task (which is to give itself another task) every few seconds.
Related
When a user enters an activity on my app I want to perform some logic during onStart and possibly launch a second activity before letting the user see the first activity (think of this as a pin protected activity)
I have a small issue where the contents of the first activity are shown for a second before the second activity is started. This happens when the user uses the home button to get out and in to the app. Is there a way to prevent the first activity to be visible at all before performing the logic validation?
This is more of a "design" solution to your problem and not clear if it'll work for you. I had something similar in the app I'm working on. What I did instead, was to create an interstitial Activity that resembled the same starting state (i.e. not yet completely loaded) of the Activity (Pin-protected Activity in your case) that is about to be started. Once I'd made my appropriate decision about whether or not I could go on, I just navigated to that initial Activity. In your case, I could see you making the decision on this interstitial Activity, and then navigating to the Pin-protected Activity or to the other one if conditions were not met properly.
The only downside to this approach is that the app does a quick flash with the additional Activity, but I think the increased separation of logic is worth it.
I'm making a simple e-book reader app, and an activity can be called by many cases.
I'd like to distinguish callee activity to know its origin action in case of
From my another activity: this can be easily solved by
StartActivityForResult from calling activity.
Called by back button click from other package app after share action ("whoops, I missed to click share button, and then back.").
Switched by user's multitasking choice.
Called by user click at the start screen: this might be known by MAIN entry point at the android manifest.
How to know above cases?
I have no idea why you would need to do this but...
1.From my another activity: this can be easily solved by StartActivityForResult from calling activity.
Yes, as long as the calling Activity is your own as you can't guarantee any 3rd-party code will use startActivityForResult(...). You can, however, use getCallingPackage() and getCallingActivity() in other cases.
2.Called by back button click from other package app after share action ("whoops, I missed to click share button, and then back.").
When the user presses the BACK button your Activity isn't being "called" - it's simply being resumed or re-started. The original calling app/Activity/method will still hold true - there is no way to ascertain that this has happened as the normal Activity life-cycle methods (onStart() and onResume()) are always called even when an Activity is first created.
3.Switched by user's multitasking choice.
If you mean using the "Recent" apps view, the same applies for my answer to 2. above.
4.Called by user click at the start screen: this might be known by MAIN entry point at the android manifest.
In this case onCreate() will be called although if your Activity is simply stopped for whatever reason, it may simply be restarted depending on the launch mode you use.
In short, I can't see you being able to gather much in the way of any accurate information as to how your Activity becomes active.
I am not too sure about the actual way for the above question as I am too a new guy in android.
But to the best of my knowledge... called by back button and switched by user's multitasking leads the activity to enter pause state.
So you can access it from "onPause" method in your activity.
I have an Activity that should only get created once. That is, onCreate can only be called once. If it's called again, I want the Activity to do nothing.
Is it advisable to do the following?
protected void onCreate(Bundle savedInstanceState) {
this.setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
super.onCreate(savedInstanceState);
if(onCreateWasCalledAlreadyBoolean) {
setResult(RESULT_OK);
finish();
return;
}
//Do other stuff here
}
I assume you understand how the activity life cycle works. I mean, you are not trying to avoid something that does not apply here (thinking that onCreate may be called multiple times whenever it just onRestarts etc.).
Technically, it's perfectly fine.
However, you should be worrying more about why you need to call your activity ("A") again if it shouldn't be created at all, if that's what you're thinking.
If you've caught yourself checking if your activity A was already "called" (?), this could mean the previous activity ("B") has a mistake in the logic flow of the app, and that B instead should be checking if it must in fact start that activity A. I mean, if you need to decide if you must call an activity, check before starting it.
I don't think that's applicable if you're restarting the activity (e.g.: go Home, then navigate back), but then again you should be restarting it from where you left (B for what I can tell). You won't be navigating back to A. And you didn't give much detail, so I'd guess this is some kind of splash screen, like evilmage93 said.
If that's indeed some kind of splash screen, I would advise to show it whenever the user navigates back all the way to remove your app from the task stack (contrary to his advice). In other words, whenever the user restarts the app from its "front door".
Although that's ultimately a design decision, I prefer to see the splash screen whenever the app is being loaded ("entered") in the stack for the first time, and it should work fine if you (obviously) finish A before calling B (the splash screen is supposed to finish itself when done, even in its first run). It's a matter of consistency: the same app should behave the same way whenever the user performs the same task (start app from its "front door").
Still, I answered your question covering some general aspects because you asked in such way.
// edited:
Finally, by looking at that onCreateWasCalledAlreadyBoolean I'm afraid you may be trying to reinvent part of the activity life cycle mechanism. In this case, don't: proceed with your regular activity logic because the user expects that behavior. Generally I wouldn't advise people to break the normal loading of an activity just because it was killed and restarted by the system.
I don't see why not. Wouldn't it be simpler to not restart the activity at all though?
What are you worried about NOT being okay? Performance..Uncaught exceptions..Code clarity?
I'm trying to kill 2 activities on the onclick of a button. The current activity and the previous activity. Using their pids. I'm just able to kill one activity. Why does this happen?
public void onClick(View v) {
android.os.Process.killProcess(pidofmain);
android.os.Process.killProcess(android.os.Process.myPid());
}
If I see in my logcat, The activity with pid "pidofmain" is getting killed whereas the current activity is not getting killed.
"pidofmain" is an integer i received from the previous activity using an intent.
Leave process killing to the OS. This is bad for any kind of program in a timesharing OS. If you want to conserve memory or something like that, let the OS handle it.
Also you can't really know if the process was correctly killed because well, if it is you wouldn't know, and if it doesn't you were not supposed to do it.
What do you want to do this for?
A much better way to do this is to call finish() for the current activity. You can also signal the previous activity to finish if it calls the current activity using startActivityForResult(Intent). The current activity would call setResult(int) before calling finish() to send a return code back to the previous activity. The previous activity can test the return code in onActivityResult(int, int, Intent) and also call finish() based on the result code.
Killing processes should be left to the OS. Once the activities finish, the will kill it off if it needs the resources. Otherwise it can let it around, which might help speed up a relaunch of your app if the user wants to run it again.
This isn't a definitive answer, but more like some thoughts that I have but it's too late for my to fire up Eclipse and prototype them. If it doesn't help you let me know and I'll try to look into it deeper tomorrow night.
A few thoughts (I hope they help):
1) Android apps really are single-threaded, and your main activity controls all the dispatch events (including events to what I assume to be a second thread that you created). If you kill the main activity, I'm pretty sure that your application would terminate execution immediately following your first call to android.os.Process.killProcess(pidofmain), and you'd never make it to your second call because you would have killed your entire application. Again, this is assuming by the variable name pidofmain that you are killing the main UI thread and not just an activity called main.
2) I'm a little curious also about where you got pidofmain? It sounds like you have three activities total, and in the first activity you get it's process id and send it to the second activity in an intent bundle, which also gets passed along to a third activity (which is the place where you're trying to kill this whole thing)? If that is the case, and you're trying to kill the currently running activity, the table in the documentation here leads me to believe that you can't just kill an activity that's in the resumed state using the same method. Official Android Docs for Activity You might want to try calling the finish() method for your currently running activity.
What exactly do you see in logcat? And what happens in the UI? Does the visible activity continue to run, but the other activity has been removed from the backstack?
I'm building an application using a service and the fragment compatibility pack and am running into some weird behavior. I have a FragmentActivity and a ListFragment which implements LoaderCallbacks, and when the FragmentActivity starts it kicks off a service to download data and fill in a database.
Suppose I'm on that screen, and I navigate past it by clicking on one of the rows of the ListFragment. If I then hit a nullpointer, or any other exception that causes the regular force close dialog to pop up, I hit the force close button on the dialog and the activity I'm on does indeed get shut down, but I end up back on the FragmentActivity screen, rather than say my Android/launcher home screen.
To me this says that the app is crashing but somehow the fragment activity is getting restarted. The behavior occurs if I hit the red stop button in the debug view in eclipse - the current activity gets killed but that damn fragment activity is still there.
Obviously I don't want my app to ever get a force close dialog, but really what I'm trying to figure out is if this is a symptom of me not coding something correctly. Currently I never stop the service, mostly because it gets reused over and over again throughout the app and I haven't gotten around to coding up a way to close the service safely without prematurely ending a new request to it.
Is the service keeping a reference to the Activity via the ListFragment and LoaderCallback or something? Why is this FragmentActivity seemingly invincible?
This is happening because your process is killed, but there are other activities on the activity stack. This is the expected behavior, as the system attempts to start a new process on the next activity on the stack once your offending activity was removed. See here and here.
If you want to remove all of your activities off the stack after a force close, one thing you can do is hit the back button until you are taken to the home screen. Unless you override the behavior of the back button in your app, it destroys your current activity and takes you to the previous activity. Once there are no more activities left, you will be taken to the home screen and can start your app again from eclipse, and it will start you off at your main activity.
i had run into similar problems, with Databse loading and Nullpointer Exceptions. I don't know your special case but it might help to separate the Databse out into a Content Provider if you aren't already doing that, that way you are decoupling the Fragments form the Database more, it might help with the errors.