I want the ability to start my activity in a new process and end the current instance of my activity in its current process.
The second part is easy enough with:
android.os.Process.killProcess(android.os.Process.myPid());
The first part I can not find a documented way to do. I can however get the same effect if I do the following:
((Activity)context).setResult(reason);
((Activity)context).finish();
android.os.Process.killProcess(android.os.Process.myPid());
where the activity was started for a result. This seems to work every time. The only side effect is when my activity has no title there is a brief flicker as the new instance removes its title. The activity restarts and the onActivityResult is called with the parameters I had set before killing the last instance of the activity.
Even though this works every time for me now my concern is that this will not work under some circumstances I have not tested or may be considered a bug that is removed from future OS versions.
Is this an expected and correct behaviour?
Related
I'm designing an app composed two activities. The first one always run, and is asked to trigger a second one when some stuff happens. This works fine with the standard code used for running activities:
Intent myIntent = new Intent(this, allarme.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myIntent);
however, the activity in allarme.class is not started if i'm using another app (i.e. gmail),
whilel it works perfectly from home or when the screen is locked.
I'm sure that the first activity is still running, it's just that the second action is not triggered.
Should I change anything in the manifest file to fix this?
I'm not really clear about what you want.
but I guess you want to run two activities simultaneously, am I right?
while one activity run in background and one activity update the UI.
always keep in mind that Android architecture only allowed one activity to run at the time. If you want to pass the data from Asynchronous Task, you can call the method from that class and let your handler 'recent' class update the UI.
You can create a background service that always run at background even if you are using another app or phone is locked. Here is link for more help :
http://developer.android.com/training/run-background-service/create-service.html
Thanks everybody, I think I solved it.
Basically, I found out that an activity already running can be brought to focus when re-started with a basic startActivity. Then I can immediatley switch to the new activity without losing the focus.
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?
Newbie question... So I have two activities, Cherry and Apple, and each one has a button on it to go to the other one. So back and forth.
In class "Cherry" I say this:
intent = new Intent(Cherry.this, Apple.class)
startActivity(intent);
Meaning that it should go to the Apple. There's similar code in the Apple activity.
What I think I am seeing is, is that each time when I startActivity Apple for example, it's starting a new instance of it instead of just reactivating Apple. I've scoured the doc and can't find the flag or other call that would do what I want.
Any tips would be appreciated!
-- Pito
What about FLAG_ACTIVITY_REORDER_TO_FRONT?
FLAG_ACTIVITY_CLEAR_TOP is also quite useful, finishing activities on the back stack until the target activity is reached.
To be clear, your activity may be restarted even if using the flags above. This would happen if your activity were destroyed in an attempt to free memory. In other words, you still need to make sure your activity can handle being restarted, taking the proper precautions in onPause and onSaveInstanceState.
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT will bring the launched activity back to front if it's already running as given here. You will have to handle the back button yourself so as not to finish the current activity.
In one activity I need to start another one but with one condition: if it was started before then it must be finished and started again. This activity show some information about system state (Theme.Dialog style) it also can start some services and so on. As far as I know when I do startActivity(intent) then onResume() will be called (if activity was started before). Does anybody know how to do it?
That's precisely how it should work. If you need to adjust the values on-screen, put that code in onResume(). What may not be obvious from its name is that onResume() is called when the Activity is first created as well. It's always the last method called before an Activity becomes active.
use the NEW_TASK_LAUNCH flag in the startActivity() call. Read documentation http://developer.android.com/guide/appendix/faq/framework.html#4
In the manifest file, in the activity attributes, you have the attribute launch mode, which let you specify how the activity must be launched (http://developer.android.com/guide/topics/manifest/activity-element.html#lmode).
Take a look at the description to see which mode suits most your needs. Then when the activity is brought to front, you can restart your service by overriding the Activity.onResume() method.
In one activity I need to start another one but with one condition: if it was started before then it must be finished and started again
There is nothing that only does this. The closest is to have the combination of FLAG_ACTIVITY_CLEAR_TASK|FLAG_ACTIVITY_NEW_TASK, but that has other side effects, such as wiping out any other activities.
As far as I know when I do startActivity(intent) then onResume() will be called (if activity was started before).
Not by default. By default, a second instance of the activity is created.