How can i run an async task when an activity starts? there are about 7 activities, and i need to run the async task, every time one starts, and cancel it when the activity dies.
public MyApp extends Application{
public void onCreate(){super.onCreate();}
}
One obvious way would be to put it in onCreate of every activity, but that is not very DRY. Is there any other way? If I put it in the Application onCreate, then I am unable to execute, Toast.makeText, since I guess no activity is available...
First of all your Code uses the onCreate-Method of the Application Class. In general you should avoid doing stuff here, but use your Activity class. You should be aware of the difference between Application and Activity and should have a good understandig of the Activity-Lifecycle because this are Android fundamentals.
For common tasks to all Activities you should create your own probably abstract BaseActivity , implement common/shared stuff there and inherit from this class. But keep in mind, that several Activities might be instantiated at the same time, so the right handlers to use really depend on what kind of behavior you want to achieve. Again: Understand how the android life-cycle works and how activities are managed or you might run into some trouble.
Have you considered creating a service to host your task, and binding it in each of your activities' OnCreate ?
Related
I have an application that runs a background thread which periodically performs a task. The UI thread moves through several different activities.
The tutorial I used can be found at this blog, the gist of it is the following:
Create a class that extends Thread
public final class JSONThread extends Thread {
Define a method in this class that adds a task to the MessageQueue, prompting executing when able.
public synchronized void enqueueJSON(final JSON.JSON task) {
However, after creating the initial object in my main activity, navigating to another activity obviously loses the Object bound to my Thread. I am no longer able to call methods on that Object (hence unable to add to queue).
I am unsure if this is caused by a wrong decision in architecture on my part or by overseeing the obvious solution. Any ideas? Note that I am trying to avoid AsyncTask for this purpose, since a pool of five threads for a simple task seems a little too much.
You need to store a Thread object as member of some other object with lifetime longer than Activity.
Two ideas for you:
a) It could be a member of Application (http://developer.android.com/reference/android/app/Application.html)
You may have problems with this, if you don't have a Service running. There is no guarantee that your application won't be killed (as example if any system dialog will pop up on top of your activities)
b) It could be a member of Service
(http://developer.android.com/reference/android/app/Service.html)
You should be using a service, not a thread. A service will remain in the background so long as there is an activity bound to it, and it won't be reset when an activity exits.
Is there any way to handle when my android application goes into background and back?
I want to use notification service for a on-line game - I use a service, which shows an alert when something happens in the game. I want alerts to show only if my application is active (on the foreground), so I need to start my service when application goes foreground and stop it when application goes background.
Note that I cannot use Activity.OnPause/OnResume methods. I have many activities in my application, and if I'll handle OnPause/OnResume, it is possible in a moment, when a user swtches one activity to another, application will look like background, thorough it will be foreground actually
Note that I cannot use Activity.OnPause/OnResume methods. I have many
activities in my application, and if I'll handle OnPause/OnResume, it
is possible in a moment, when a user swtches one activity to another,
application will look like background, thorough it will be foreground
actually
Why don't you write a base class that extends Activity and enables or disables the service in these methods? After that extend all your activities from this base activity.
All you have to do is call the superclass method if you override these methods in your activties, e.g. by calling super.onResume() inside onResume(), to make sure these get still called. If you don't override them, everything works directly.
Not a clean way of doing this that I know of but,
You could perhaps send an Intent to your Service onCreate() and onPause() with a unique identifier.
You Service can then start a timer (with a delay which will be longer than the difference between onPause and onCreate being called in each activity) which, if not notified of an onCreate() within this time will set the Activity as "Paused".
If you add this functionality in a parent class which extends Activity you can then pull this same functionality into every class by extending that it rather than Activity (with the contract that you must call super.onCreate() and super.onPause() in each respective method).
Problem solved in a following way (C# code, mono for android)
class MyService : Service{
OnSomethingHappened(){
ActivityManager am = (ActivityManager) GetSystemService(ActivityService);
if(am.RunningAppProcesses.Any((arg) =>
arg.ProcessName == "myprocessname" &&
arg.Importance == ActivityManager.RunningAppProcessInfo.ImportanceForeground
)){
Trace("FOREGROUND!!!!");
}else{
Trace("BACKGROUND!!!!");
}
}
}
In my app I need to call code whenever the app closes (pauses) and then run code again whenever the app starts again (resumes). For example, I call a web service that syncs the data whenever the app starts or exits. This is easy in iOS because of the central app resume and suspend methods.
I understand the OnPause and OnResume in the Activity, however, is there a central way to handle this? The user could leave the app on Activity3 and come back later, or be in another screen, etc. I'd hate to have to have the same code in every Activity's OnPause and OnResume to handle the "app" startup and shutdown code routines.
Any suggestions?
Thank you.
You could make a common Activity which just handles onResume() and onPause() in a certain way and then make every Activity extend from that one instead of Activity directly.
I would consider subclassing Activty, have each of your activities extend that and just do what you need to when any of them pause or resume.
You could use some static members in an Application class that your new activity base uses to track state or store whatever you need.
Also, Application class has an onCreate() method which will run each time the application is started. There is no pause or resume for Application, however.
Creating a main Activity that is extended by all your other activities and override the onPause and onResume.
But the problem you will face if you want to extend another Activity class such as a ListActivity.
Another approach is to create a new class that extends application and override its onCreate and create a static method that acts as onPause and manually call it by each of your activities
What is the proper way to manage threads working in the background?
For example, I have Activity that creates several threads. I need to do following:
1) Destroy all threads when Application is destroyed
2) Pause threads created within Activity if user navigate away from Activity
3) Destroy threads created within Activity if Activity is destroyed
The only thing that come to my mind would be to have all threads variables declared as public the to be able to issue t.destroy() or something similar on these events that I listed above.
First, I am not sure if this is right way at all, and secondly, I don't like it because I will have to change code to make sure I can reference all threads I created.
For example, I have situation where my Activity instantiate new object (ex. LoadImages.class) and that objects creates several thread depending on how many images is to be loaded. The threads are not visible from the calling activity.
So, do I have to pass threads references to calling activity, or there is some way to know who is the parent of the thread and destroy only thread with particular parent Activity?
For LoadingImages I think there is a simple solution: have a public method on LoadingImage called release that will allow it to release its own resources.
If each of your activities is destroying its own threads, I don't see the need for your step 1.
I have a class that fetches data in response to button presses in the main activity. Unfortunately, I keep running into problems because this class is not an Activity or a Service. For example, without a Context I cannot translate a resource id into a string:
getString(R.string.example_string); // Doesn't work
Should I make this class into a Service and have the main Activity stop the class when it is closed? Should I pass the Context from the Activity into this class like this?
MyClass c = new MyClass(this);
Or is there some better way to handle this problem?
This issue also comes up when I try to send a Toast from this class.
Update: Erich and Janusz pointed me in the direction of the AsyncTask class which works perfectly, except that it creates a new thread and never kills that thread. This means that ever time the user presses a button, another thread is added and the old ones just sit there.
If you have a background action whose lifecycle is decoupled from your activity, I would use a Service. In that case, the Service will have its own Context, so you won't need to pass it in. If, however, you need to perform a background action in response to a UI event (and optionally post the results back into the UI thread), I would recommend you use an AsyncTask.
I agree with Erich, if you only have a something small like posting a change to a web backend or loading something from the phone memory to show it on screen use a Async Task. If the task will exit very "quick" (some seconds) you can make an anonymous class inside your activity. This will enable you to use a implicit reference to the outer activity inside the task and you can get your context from there.
If the task is running for a longer time you can pass down the context. If you are passing down the context try to not pass this from the activity use this.getApplicationContext() this will minimize the number of references to your activity and enable the garbage collector to clean up properly.