As I understand - both Runnable and Service are intended to run piece of code in background. My code structure is this:
BaseManager.class which is implemented as Singleton and using BaseManager.getInstance() will return single instance in application. Also, when first initialized it automatically creates SmallerAndCompletelyDifferentManager.class - has a dependency.
SmallerAndCompletelyDifferentManager.class - creates a Runnable that runs every 2 seconds.
Now, I've two scenerios:
SCENERIO A: I create initialize BaseManager.class in Activity first and use it wherever I need. The Runnable that is inside SmallerAndCompletelyDifferentManager.class runs okay, but as I understand is attached to Activity - if Activity dies, so will the Runnable which I can not afford.
SCENERIO B: I create a foreground service and initialize BaseManager.class. Does this mean that now the Runnable will work as intended - even if application is in background and Activity has been destroyed?
Am I getting this right or no? The overall plan is to make sure that Runnable survives in background at all costs.
As I understand - both Runnable and Service are intended to run piece
of code in background
This is not correct.
Service is an application component that can be perform long-running operations in the background. Here background means you do something behind the scene (or background) when users interact with the app, or when users switch to another apps.
Runnable is a block of code that can be run, that why it has the name "Runnable", it means something can be run/execute. The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.
In Android there a two types of thread, the first one is main/UI thread and another one is background thread. Here background means when you do something in a thread rather than main/UI thread.
Back to your case
In scenario 1: The Activity creates Runnable and keep a reference to it. When you destroy the activity (by press Back button or call finish() method), the activity will be destroyed, and the runnable will be released.
In scenario 2: The foreground service creates Runnable and keep a reference to it. When you destroy activity or switch to another apps, the service is still alive (and runnable as well) until you kill service by calling (stopSelft() or stopService() method). Because when using a foreground service, it will tell the system that the app is doing something important and it shouldn’t be killed.
As I understand - both Runnable and Service are intended to run piece
of code in background.
To be more specific, Service runs on a main thread. It is your responsibility to put the work on a separate thread if you are planning to make a CPU-intensive work inside the service. You can do so by putting it inside a Runnable or a Thread.
Am I getting this right or no? The overall plan is to make sure that
Runnable survives in background at all costs.
Scenario B could work but my suggestion is to modify your BaseManager into a service class.
Related
Recently, I am studying a code about printer Bluetooth connection.
The program try implement runnable in the MainActivity.
Here I would like to ask 2 question.
1.How can I execute the activity as a thread when there is no other program calling run() of this activity?
2.Is there any special meaning for implementing runnable in MainActivity? Are ther any difference between implementing runnable in a class other than MainActivity?
I am not too certain what you are asking in the first question because code inside Activity will always run on the main (UI) thread by default.
To answer your second question, the MainActivity is probably implementing the Runnable interface only to define some code that can be executed on a Thread later.
For example, you can call runOnUiThread (Runnable action) from the Activity, passing MainActivity.this as the runnable parameter to execute code on the main thread.
You can also spawn a new thread with the runnable to have it run in the background or post it to a handler.
There is a sequence of callback methods that start up an activity and a sequence of callback methods that tear down an activity.
1)Created 2)Started 3)Resumed 4) Paused 5) Stopped 6)Destroyed
However, only three of these states can be static :-3)Resumed 4) Paused 5) Stopped,,,,
Resumed State(Running state):- In this state, the activity is in the foreground and the user can interact with it.
(Also sometimes referred to as the "running" state.)
here are simply two rules to Android's single thread model:
1) Do not block the UI thread
2)Do not access the Android UI toolkit from outside the UI thread
I have an application with several activities, and I have a timer I start in the first activity that is presented. The problem is this:
How can I get a reference to the current activity when the timer goes off when the activity I'm currently may not be the same as the one I started the timer.
What I actually want is to have a timer traverse all my actives, show an alert dialog when it expires and the do some stuff. But because of the way android works this seems to be impossible. Does anyone has an alternative?
I've already tried:
Using an async task to access the ui thread, doesn'nt work if it is not created in the main ui thread.
Can't use a Handler, my timer is in another class
What other choice do I have?
EDIT:
I can´t change any of the activities code, the timer should be decoupled enough to function when someone plugs it in the project.
Getting an instance of the current activity from the timer worker thread should work, since it would let me run stuff in the ui thread.
Implement your timer as a singleton.
Then, implement an observer pattern:
Create an interface (maybe called AlertListener) that is implemented by each Activity you want to be alerted. This interface should have a method, something like onTimerExpired(). This method should do whatever needs to be done to the activity when the timer expires.
In your timer class, also maintain a reference to the current AlertListener and a method, named something like "setCurrentActivity(AlertListener currentActivity)".
In onResume or some other method of each activity, call MyTimer.setCurrentActivity(this).
When the timer goes off, call currentActivity.onTimerExpired().
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.
I am writing an Android app (ICS) for a tablet. The user moves from Activity A to Activity B to Activity C with the touch of a button. I want to return from Activity C to Activity A after 10 seconds. Is there some way to count to 10 without locking up Activity C?
I've succeeded with an asyncTask but if I startActivity(A) in the onPostExecute() it feels like I'm violating the guideline that an asyncTask should not mess with the UI. I've tried get() but that does lock up Activity C while it's waiting for the 10 seconds to pass.
Thanks in advance!
Assuming you have any View instance in your activity, you can use View.postDelayed() to post runnable with a given delay. In this runnable you can call Activity.finish(). You should also use View.removeCallbacks() to remove your callback in onDestroy(), to avoid your callback being called after user already navigated back from your activity.
Using AsyncTask just to count some time is just an overkill (unless you want to use AsyncTask to actually do some useful, background work). The Looper and Handler classes provide everything you need to execute any code on UI thread after a given delay. The View methods mentioned above are just convenience methods exposing the Handler functionality.
Using AsyncTask works fine as you describe. From Android Documentation:
onPostExecute(Result), invoked on the UI thread after the background computation finishes.
Since it is invoked on UI thread you should be fine.
Documentation
You can use a alarm manager for that. Set it to send a broadcast 10 seconds starting from activity a and implement a base activity for activity a b and c to receive the broadcast, after receiving the broadcast just end the current activity and start activity a with a new flag. If the current instance is activity a then ignore if not start activity a. Something like that.
As for the idle part you can update the alarm manager on every action, upon entering activity etc.
The advantage of this implementation is that you dont have to go through the hassle of having to worry about context leaks, persisting timers across activities and such. and can make use of what is already there. You can also consider using a service though.
If not you can just use the shared preference store the time to time out and check or update against it for the actions.. A simpler implementation.
Good luck.
I have seen some discussion here on Stack Overflow related to using Activity.onRetainNonConfigurationInstance() to maintain a background thread started by one instance of an Activity and pass it to the next instance of the Activity which results, for example, when the phone's orientation changes from portrait to landscape.
The discussions do not specify exactly what can be done with the thread wrapped in the Object returned from onRetainNonConfigurationInstance().
For example:
1. Is there a way to actually keep the background thread running using this technique?
2. Do you need to somehow pause the thread when the previous instance of Activity is going away and then restart it again in the new instance?
Can anyone provide a short example?
Any details would be appreciated.
You can return anything you want to onRetainNonConfigurationInstance(). If you have a Thread that you want passed from one instance of the Activity to another, you can either return it directly, or put it inside another object that you return from onRetainNonConfigurationInstance(). You don't need to pause the thread or interact with it in any way. It just keeps running as if nothing happened.
The only thing you need to be concerned about is how the Thread interacts with the Activity (if at all). If the thread will call the Activity back (to indicate progress or something like that) then you somehow need to give the thread a reference to the new Activity, as the old Activity will be dead.
What do you want to do in your background thread?
EDIT (add more details about threads/activities):
Threads have their own lifetimes which are completely disconnected from Activities. If you create a Thread in an Activity and start it, it will run to completion no matter what your Activity does. The only thing that will stop the thread explicitly is if Android decides to kill your process (which it may do if your process contains no active activities).
The thread will continue to run. For an example of what you can do with this, you can check out the android Ignition project and its IgnitedAsyncTask (and related examples).
The idea is that you will maintain a reference to your thread (usually an AsyncTask) somewhere in your Activity, and occasionally your thread (again, especially if it's an AsyncTask) will require a reference to a Context in order to perform some kind of UI update upon the conclusion of its background task. You will need to make sure that the Context (and anything derived from it--like a TextView or the like) to which your thread has a reference is non-null, or else it will crash.
You might use getLastNonConfigurationInstance() to set your Activity's reference to the thread, and then call a setter on the thread to set its Context reference (to avoid any related null pointer crash).