In my android app, there are two Activities A and B and there is a Button in A to launch B:
A -> B
I would like to launch an AsyncTask (which is an inner class of A) in the onCreate() method of A which will load some data. However, I don't want the user to be aware of that loading, that's why I launch the AsyncTask that way.
However, if A starts and the user launches B while the AsyncTask is executing, I was wondering if that would cause some Exceptions, bugs or something not right.
Is it possible to do that?
An AsyncTask always keeps a reference to the Activity, so you need to cancel the AT while destroying the Activity, ie onDestroy().
Here it's pretty well explained.
Related
I have recently started working with android. So I am in the initial stages of learning.
The question is: when we call startActivty(Intent) in the middle of execution of another activity.I actually thought that startActivity() will simply jump into the activity called. Isn't it the case? does it simply stacks the call to the activity?
I am getting this doubt bcoz..I actually have a program in which Activity A has a loop. Some where in the middle of loop Activity B is called. I want activity A to resume with the loop only when activity B finishes. I have made a call in A's loop like this:
in = new Intent(this,MyChoiceActivity.class);
in.putExtra("McObj", mc);
startActivity(in);
finish();
So What happens is Activity A calls B, but B is not entered, A simply resumes the loop and again calls B, simply the calls to B are stacked and once the loop in A completes, one by one calls to B in stack are executed so finally the first call to B is executed last(last in first out)...But I dont want the order to change...If A calls B, it should simply go and execute B and only then come to the loop..what should I do to accomplish this?
Your activity can be busy and just 'be there'. If you start a new activity while your activity is really doing something, it will not 'wait' until the other activity is finished: both can be around at the same time.
If it would do this, it would have you end up with a lot of busy-waiting processes, so luckily this is not what happens.
See the activity lifecycle to find out more about what an activity is (it is not just another class as you are using it now, it starts a separate thing that hangs around next to (not instead of / on top of) your current activity).
Instead, beacuse these things go rather asynchronous, you might want to use a different approach: use an ActivityForResult, and start a new one when you get that result.
I'm talking about programming in android.
In early days I thought that, finish() closes current activity and go back to the previous in Activity stack, and System.exit(0) closes the whole application.
But I was wrong.
I made a small experiment and understood that Both will finish only the current Activity.
The only differences that I could notice is that, in Android 2.3.3
The ActivityResult is propagated back to onActivityResult() using finish(). Whereas onActivityResult() not called for System.exit(0).
But in Android 4.2.2, onActivityResult() is called for both! and Intent was null for exit().
(I tested only in these 2 devices)
There is a time lag when using exit() whereas finish() is faster.(seems like more background operations are there in exit())
So,
what's the difference between two?
In which situations, I can use exit()?
I believe there is something more that I'm missing in between the two methods.
Hope somebody can Explain more and correct me.
Thanks
EDIT UPON REQUEST:
Make an Android application with 2 Activities. Call second Activity from Launcher activity using Intent. Now, inside the second activity, upon a button click, call System.exit(0);.
"The VM stops further execution and program will exit."????(according to documentation)
I see first activity there. Why?
(You are welcome to prove that I'm wrong/ I was right)
Actually there is no difference if you have only one activity. However, if you have several activities on the stack, then:
finish() - finishes the activity where it is called from and you see the previous activity.
System.exit(0) - restarts the app with one fewer activity on the stack. So, if you called ActivityB from ActivityA, and System.exit(0) is called in ActivityB, then the application will be killed and started immediately with only one activity ActivityA
According to android Developer -
finish()
Call this when your activity is done and should be closed. The
ActivityResult is propagated back to whoever launched you via
onActivityResult().
System.exit(0)
The VM stops further execution and program will exit.
According to the documentation, The program will exit.
But it seems a bug in the documentation. In case of a java program, it is correct. But coming to Android, You will see the previous Activity from the stack.
Since Android coding is done using java coding, most of the documentation is same as those for java.
From documentation,
System.exit(0)
The VM stops further execution and program will exit.
For Android aspect, we have to replace the word 'program' with something else. May be Activity or Context.
Sa Qada answer is correct after my testing.
finish will close this activity and back to prevous.
but exit will close current activity too and empty all the activity in freeze and start again the previous activity
Actually there is no difference if you have only one activity.
However, if you have several activities on the stack, then:
finish() - finishes the activity where it is called from and you see
the previous activity. System.exit(0) - restarts the app with one
fewer activity on the stack. So, if you called ActivityB from
ActivityA, and System.exit(0) is called in ActivityB, then the
application will be killed and started immediately with only one
activity ActivityA
So I have two activites where I can switch between. Let's call them ActivityA and ActivityB.
Now if I'm in ActivityB and it somehow crashes and I start my App again it should appear the ActivityB and not A.
I thought of SharedPreferences(I already used it for the switching) and savedInstanceState, but can the last one handle with the savedInstanceState of other activites or just by its own?
Can I somehow tell ActivityA to look if there is already an instance of ActivityB and if so ro start it immediately?
When an app starts, Android always runs whichever activity it is told to (as defined in the manifest) - which can work to your advantage. You should be able to create a splash activity that determines what the last activity was (via tracking, sharedPrefs or perhaps savedInstanceState - I haven't mucked with the latter much), and then launch the appropriate activity before finish();-ing the splash activity.
Make sure the splash looks decent though - add in a handler that will keep it up for at least 1500-2000ms.
I have 2 activities. Main Activity A & Activity B
I do not want Activity A to destroy. I am starting Activity B in a new task.
public static void startActivity(Class<?> startClass) {
Intent intent = new Intent(Constants.getActivity(), startClass);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Constants.getActivity().startActivity(intent);
}`
Constants.getActivity() returns the Context on current activity
startClass is the either activity "A" or activity "B"
Thing is they create/destroy the activities and they leak. Am I doing it wrong? How can I start activity "B" from activity "A" and vice versa keep them both in background when I dont need them.
First of all, what are you trying to do? You should always separate things you want to do in the background from your UI. Think of your Activities are simply a container to show the UI, everything else can be stored and restored from persistent storage or savedinstance bundles.
It is very crucial that you understand the difference between Activity lifecycle and Service lifecycle here.
I'm going to refer to my answer from another question here:
Your app will be in the background, onResume and onPause will both be called, provided that the OS have enough memory to keep the new app and all the old apps.
If you have a long running process that you need while the user not looking at it, use a service.
If you need the user to return the app in the same state, you need to do the work in onResume and onPause to save the state information and initialize your UI again when the user comes back. If you are really worried that it can get killed (well, it shouldn't lose the bundle I think), you can store them in SharePreferences for your app.
If you want to know when the app returns from that specific share intent, use startActivityForResult
You cannot keep an activity "alive" as you said. When an activity is paused, Android system is always able to claim its memory and unload it, at any time.
But if you want to switch from A to B, then maybe A and B can be different views inside a single activity. Maybe you'll want to have a look at http://developer.android.com/reference/android/widget/ViewFlipper.html
When you use tasks, cleanup is very important. You need to cleanup all tasks in the activity. readthis
If the activity does not have a lot of crazy initialization, just use finish and onCreates. Else be aware that onResume will be called often as you switch between activity's. Cleanup will be crucial here. If you dont cleanup, its possible one of your activities (with dead object reference from the other cleaned up activity) may come back up from the activity stack and throw exceptions. Its very difficult to debug this kinda exception.
I'm writing a simple Android app, and I'd like better control over the navigation/relationship between the activities. I don't want my activities to act like android activities...I don't want them to stack up within the Task. I want one Activity (let's call it MainActivity) to be the landing point and always be at the bottom of the stack, and I want only one instance of my second activity (call it SecondActivity) to be above it in the stack...would be nice to reuse it as well. I thought I could get this behavior by making MainActivity be the "main" Activity, and declare them both as launchMode=singleTop. This isn't working at all. I provide navigation between them using menus, so when I go back and forth a bunch of times and back out of the app, I go through the whole stack.
How's the best way to have fine control over the Task's Activity stack? I want MainActivity to always back out of the app, and SecondActivity to always back into a single instance of MainActivity. As well, I'd love to get singleTop working so I would use onNewIntent instead of creating and destroying every time. Using the manifest as well as the intent flag is just not working. Any ideas?
Well, you could always just call "finish()" within whatever Activity is calling another activity after the "startActivity()" call. I would definitely advise against trying to stuff an entire app into two activity classes and try to swap views based on what they're doing. If it's that important to you, just close your activities as you launch new ones (obviously not the MainActivity, though).