I started activity from service by getting gcm message from servers. If I get the message twice, than activity starts two times and if I click on back button and call finish() method than above activity gets closed. And then again click back button no activity happens.
Intent notificationIntent = new Intent(context,
NotificationAcceptBookingActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
notificationIntent.putExtra("bookingId", booking.getBookingId());
getApplication().startActivity(notificationIntent);ss
You shouldn't be having more than one instances of an activity alive at a time. However, if you still want it, maybe clearing the activity stack can help you with it. When starting the last activity, use
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
to clear previous activity stack, which will kill 2 (or no matter how many) instances of the activity.
Don't try to create new instance of the activity again and again. Before starting the activity just close it if exists.
Related
I have an Intent which starts/open an activity/window that is triggered by an alarm. Everything works fine, however the Main activity/window of the Application is also open behind the first activity referenced above when triggered. Thus, when this activity is dismissed (with the help of a button), the Main window of the Application is displayed on the device. How can I open my activity without opening the Main activity of the Application? Basically, the user shound't be seeing the Main activity of the Application upon dismissing the activity triggered by the alarm. Please note that I am not explicitly calling the Main activity upon opening the specific activity mentioned above. Is this normal behaviour, or am I doing something wrong?
The specific activity is launched with the following lines:
Intent intentRead = new Intent(context, myActivity.class);
intentRead.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intentRead);
Problem
Your code starts a new Activity in a new task :
Intent intentRead = new Intent(context, myActivity.class);
intentRead.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intentRead);
The Flags make sure that the new activity gets its own task and the activity will not be launched if it is already running at the top of the history stack.
Now, suppose your MainActivity is already in the background(recent apps) and alarm is triggered which starts your myActivity. If no instance of myActivity is present then a second task is created for it. Else if an instance is present then the all activities on top of myActivity in the second task will be removed.
Solution
In your case, as you want to clear any other activities present you should use :
Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK
Intent.FLAG_ACTIVITY_CLEAR_TASK
If set in an Intent passed to Context.startActivity(), this flag will
cause any existing task that would be associated with the activity to
be cleared before the activity is started. That is, the activity
becomes the new root of an otherwise empty task, and any old
activities are finished. This can only be used in conjunction with
FLAG_ACTIVITY_NEW_TASK.
Suppose the first activity is started by your main activity, could you just finish main activity after starting the first activity. I mean like this:
startActivity(MainActivity.this, FirstActivity.class);
MainActivity.this.finish();
I read several similar questions here, but I didn't find a clear reply to my question.
I launch my Android App and I have my main ActivityA in foreground
after some time I push a button (of ActivityA) and I open (and put in foreground, then visible and ontop) ActivityB. I do it simply by the command myContext.startActivity(myIntent);
It means that now ActivityA is in background (onPause()), then not visible.
After some time I push another button of ActivityB with the target to put in foreground (then visible and ontop) again previous ActivityA
What is the correct and best way to do it? According to my understanding (but I'm not sure it's correct.) it shouldn't be by startActivity(), because startActivity() creates another instance of ActivityA (it calls onCreate() ) and then there will be 2 instances of ActivityA running (one in foreground and one in background). What I want to get is a calling of onResume() for ActivityA (and not of onCreate() ).
The second question is: how can I know if ActivityA is still alive in background? Maybe after sometime the system killed it to free resources.
Note: the solution in my case cannot be to use finish() to destroy ActivityA when I open ActivityB, and then to use startActivity() to reopen it, because I need ActivityA alive as much as possible.
Thank you very much in Advance
Fausto
What you need is the FLAG_ACTIVITY_REORDER_TO_FRONT when starting a new activity. This will cause a background activity to be be brought to the foreground if it's running, or create a new instance if it's not running at all.
From inside ActivityB:
Intent intent = new Intent(this, ActivityA.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
What is the correct and best way to do it?
Use startActivity(), with an Intent on which you have added Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.
it shouldn't be by startActivity(), because startActivity() creates another instance of ActivityA
While that is the default behavior, Intent flags can alter that behavior.
how can I know if ActivityA is still alive in background?
If you did not finish() it, and your process has not been terminated, it exists.
Maybe after sometime the system killed it to free resources.
Android terminates processes to free up system RAM. It does not destroy activities on its own.
because I need Activity A alive as much as possible
To be honest, that suggests that you have other architectural issues. Bear in mind that activities are destroyed and recreated for various reasons, such as configuration changes (e.g., screen rotation). Activities should be very disposable.
You can use following
1. For launching new instance (current state of ActivityA) and get ActivityA on Top of Stack
Intent intent = new Intent(this, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
2. For launching old instance and get ActivityA on Top of Stack
Intent intent = new Intent(this, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
For more detail please check
Task and Back Task
You can use StartActivityForResult in the place of StartActivity in activity A and on activity B you can setResult when you want to open Activity A again.In that case OnActivityResult() of activity A is called not onCreate().
Android: when coming from notification, activities are added on top of already open activities and memory increases.
How to clear all the previous activities or even kill the app when notification is tapped?
Here is how I build my notifications:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)//
.setContentTitle(notificationTitle)//
.setContentText(notificationText)//
.setSmallIcon(R.drawable.app_icon_transparent)//
.setAutoCancel(true)//
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.asd));//
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(context, StarterActivity.class);
resultIntent.putExtra("comingFromNotification", true);
// The stack builder object will contain an artificial back stack for
// the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(StarterActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify((int) now.getTimeInMillis(), mBuilder.build());
Now, when the user receives a notification and clicks it, StarterActivity is started. It initiates all the resources the app needs and then starts the main activity.
If the app had been running up to this moment and had been taking up 50 mb of ram, now ram goes up to 65, which means the previous process is not killed and this one starts on top of it.
Question is, how to kill the app if its running in the moment the user clicks the notification?
EDIT: In some similar question I found this
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_NEW_TASK);
will this help? What do these flags mean?
EDIT2: Nope. those flags didnt help. The application process that has some cached objects in memory still lives and the RAM goes up again.
Your architecture doesn't lend itself to solving this problem. As you mentioned in some comments, StarterActivity is your root activity (ie: the one with ACTION=MAIN and CATEGORY=LAUNCHER), but you don't keep it in the activity stack, so you cannot take advantage of FLAG_ACTIVITY_CLEAR_TOP.
To solve your problem you should not call finish() on StarterActivity when it launches MainActivity. This will allow you to use FLAG_ACTIVITY_CLEAR_TOP (with or without FLAG_ACTIVITY_SINGLE_TOP, depending on whether or not you want to use the existing instance of StarterActivity or create a new instance).
Once you've got that working, you now need to deal with the problem of the user pressing BACK in MainActivity and having it return to StarterActivity, which is obviously not what you want. You can solve that in several ways, here are 2 examples:
Add a boolean member variable to StarterActivity. In StarterActivity.onResume() set that variable to true at the very end of the method. At the start of onResume(), check the variable, and if it is true, you can assume that the user has pressed BACK in MainActivity, so you can just call finish().
In MainActivity override onBackPressed() and instead of calling super.onBackPressed(), call startActivity() with an Intent for StarterActivity with an extra named "exit" and FLAG_ACTIVITY_CLEAR_TOP. This will cause a new instance of StarterActivity to be created. In StarterActivity.onCreate(), check the presence of the extra "exit" in the Intent, and if it is there, it means that the user pressed BACK from MainActivity. In this case, you just want to call finish() to end your application. If you use this mechanism, make sure that StarterActivity has standard launchMode in the manifest, not launchMode="singleTop".
FLAG_ACTIVITY_CLEAR_TOP - Clears intermidiate activities, not every activity e.g:
You have call A > B > C > D >E , then from E you call B. After such call Activities C and D will be removed, activity A will remain.
If you have calls A > B > C > E and from E you call activity F, no activity will be purged.
FLAG_ACTIVITY_SINGLE_TOP ensures the top activity is not recreated if it is called again. eg:
you cal A > B > C , then you call B again. After such call B will not be recreated, but Current existent will be called. If you will call A, it will be recreated as it is not on top of stack.
Activity_new_task - is used for complecated back navigation. You can manage several tasks or in other words several histories of activity calls. Creating new task will not erase previos task. Is an absolute requirenment, when starting app with notification, deeplinks or any other "launcher" behaviour. Purifications inside one task will have no effect on another task history
I assume, a propper reset of history after launch will be achived with those 3 flags together: FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP |FLAG_ACTIVITY_CLEAR_TASK
This shoul, clear task history, close it and create new task. If it does not work try to replace Clear_Task with FLAG_ACTIVITY_RESET_TASK_IF_NEEDED.
You don't need to kill the app and start it again. Use android:launchMode="singleTop" in your manifest for the activity:
<activity
android:name=".StarterActivity"
android:launchMode="singleTop"/>
This will open the same activity rather than creating a new one.
I'm new to android. Actually one handler is running in Home Activity A for every 30 sec to check the net connection.
If I'm went to activity C by A->B->C, If there in no net connection at that time, then i want to close Activity B and C, then want to show message box in Activity A.
But My problem is My handler is running for every 30 sec in Home Activity A. But If i was in Activity C or some other Activity how to find which activity is my Application currently focussed now. Then i want to finish those child activities and want to show Home Activity A I have some 9 child activities in Activity B.
I heard about using "FLAG_ACTIVITY_CLEAR_TOP" . I used the code as follows in the handler in Home activity A itself. But got error.
Intent intent = new Intent( ctx, Homepage.class );
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
ctx.startActivity( intent );
Here Homepage.class is my Home Activity A and i set that activity in manifest file as
android:launchMode="singleTop"
Please help!
You can start Activity A and close all other activities.
You have to create new intent and add flag FLAG_ACTIVITY_CLEAR_TOP
Intent activityA = new Intent(context, ActivityA.class);
activityA.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.StartActivity(activityA);
this will close all activities that are in the stack and are at the top of activity A
When calling Acitivity C, call finish in activity B , when calling Activity A from C , call finish() in activity C !
You can use, According to me two ways,
If you start an activity using startActivityForResult, then you can call finish() in this new Activity when you're done with it and it will return control to the activity that started it.
OR otherwise, May be I am wrong,
Call finish inside onStop 'override method'.
make a uniform resultCode for closing child activities. Eg. you make 911 (should be int) as your resultCode. If you want your Activity to finish and go back directly to parent Activity, you set the resultCode to 911:
setResult(911); finish();
In every child activity, you override the onActivityResult and check if the resultCode is 911. If yes, then call the setResult(911); finish(); until you get back to your parent activity. Hope this helps!
For example, if you want to start intentB, you can do following in old activity:
Intent intentB = new Intent();
intentB.setClass(XYZ.this, abc.class);
intentB.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intentB);
I'm new to android. Actually one handler is running in Home Activity A for every 30 sec to check the net connection.
If I'm went to activity C by A->B->C, If there in no net connection at that time, then i want to close Activity B and C, then want to show message box in Activity A.
But My problem is My handler is running for every 30 sec in Home Activity A. But If i was in Activity C or some other Activity how to find which activity is my Application currently focussed now. Then i want to finish those child activities and want to show Home Activity A I have some 9 child activities in Activity B.
I heard about using "FLAG_ACTIVITY_CLEAR_TOP" . I used the code as follows in the handler in Home activity A itself. But got error.
Intent intent = new Intent( ctx, Homepage.class );
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
ctx.startActivity( intent );
Here Homepage.class is my Home Activity A and i set that activity in manifest file as
android:launchMode="singleTop"
Please help!
You can start Activity A and close all other activities.
You have to create new intent and add flag FLAG_ACTIVITY_CLEAR_TOP
Intent activityA = new Intent(context, ActivityA.class);
activityA.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.StartActivity(activityA);
this will close all activities that are in the stack and are at the top of activity A
When calling Acitivity C, call finish in activity B , when calling Activity A from C , call finish() in activity C !
You can use, According to me two ways,
If you start an activity using startActivityForResult, then you can call finish() in this new Activity when you're done with it and it will return control to the activity that started it.
OR otherwise, May be I am wrong,
Call finish inside onStop 'override method'.
make a uniform resultCode for closing child activities. Eg. you make 911 (should be int) as your resultCode. If you want your Activity to finish and go back directly to parent Activity, you set the resultCode to 911:
setResult(911); finish();
In every child activity, you override the onActivityResult and check if the resultCode is 911. If yes, then call the setResult(911); finish(); until you get back to your parent activity. Hope this helps!
For example, if you want to start intentB, you can do following in old activity:
Intent intentB = new Intent();
intentB.setClass(XYZ.this, abc.class);
intentB.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intentB);