In the Android docs, it says that a Service runs in the main thread.
What happens if I start my service in a separate thread? Does it still run on the main thread?
I am not talking about using android:process in the manifest file, but rather something like:
Thread thread = new Thread(new Runnable() {
public void run() {
// Start service
}
}).start();
Don't worry, I will not do it like that, I am just curious.
startService() starts a service in the main thread (the same as starting an Activity or any other component). In doesn't matter what thread you call startService() from.
Source: http://developer.android.com/reference/android/app/Service.html
"When a Service component is actually created, for either of these reasons, all that the system actually does is instantiate the component and call its onCreate() and any other appropriate callbacks on the main thread."
Documentation says that a Service is not even related to multithreading by default:
A service runs in the main thread of its hosting process—the service
does not create its own thread...
You can read it here: http://developer.android.com/guide/components/services.html
What your code does may be very similar to calling a View's functions from a Thread other than main thread. System doesn't let you do that. Throws an exception.
If you're asking out of curiosity and don't need any code:
First you have to understand the difference between a process and a thread (see http://docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html)
All the threads in your app get triggered in the app's process by default.
The Service itself is a thread so there is no reason to launch it from a separate thread (you normally launch it from the main thread, like onCreate method and such. It's launched by default in the same process but you can specify a separate process for it by specifying processname in the declaration like so:
http://developer.android.com/guide/topics/manifest/service-element.html
Related
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.
I'm developing an application that is meant to run only as a service. That is, it has no Activity (that is usually run, at least), and at any given moment, the only component of the application that will be running (usually) is a service. This is meant to be used with the screen locked. It already works.
In such a scenario, I seem to understand that the service's thread is the application's "main thread", even though it's not a UI thread proper (as there is no UI).
The question is: if the service uses a HandlerThread, can I call runOnUIThread() from a method that is called from the HandlerThread? Will this make it run from the main thread, without the need to launch an Activity (which would involve unlocking the screen)?
Basically my problem is that I need to use a SpeechRecognizer, lanching it from the service.
Right now my service is using a Handler on a HandlerThread. When trying to init a SpeechRecognizer from methods that are (indirectly) called by the HandlerThread, I get an exception because SR has to be run from the main thread.
Can I use runOnUIThread()?
I see there is a similar question here: How to invoke Speechrecognizer methods from service with no main thread or activity
However, the answer involves invoking the SR from onCreate() or onStartCommand(), which is not viable in my case.
UPDATE: obviously, I can not call runOnUIThread(), as it is a method of Activity. So is there a way to have some call run on the main thread, which is in this case not a UI thread?
This answer is not speech-recognizer specific which is why it started as a comment, but more space is needed to clarify...
Handler mainHandler;
public void onCreate() {
super.onCreate();
mainHandler = new Handler(); // this is attached to the main thread and the main looper
// ...
}
// anywhere in a background thread:
mainHandler.post(new Runnable() {
// ...
});
This code creates a handler which is attached to the main thread. Posting to this handler from a background thread will run code on the main thread as desired.
I'm not using SpeechRecognizer so I can't guarantee that it will solve the problem, but it seems like it should.
Edit: some more detail
The article I was thinking of that explains some big ideas is The Android Event Loop. In particular it links to this bit of code which shows how runOnUiThread is implemented by posting to a Handler as I am suggesting here:
/**
* Runs the specified action on the UI thread. If the current thread is the UI
* thread, then the action is executed immediately. If the current thread is
* not the UI thread, the action is posted to the event queue of the UI thread.
*
* #param action the action to run on the UI thread
*/
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
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 Android service that starts and maintains a background thread.
From time to time, the background thread needs to do a callback on the main thread. I'm stumped as to how to do this.
I can't call this.runOnUiThread because "this" is an instance of Service, not Activity, and a Service doesn't have the runOnUiThread method.
I also can't create or execute an AsyncTask, because the documentation for AsyncTask says that both the constructor and the execute method must be invoked from the UI thread.
Do I need to maintain a reference to the activity that is using the service and call its runOnUiThread method, or is there another way to run something on the UI thread?
Thanks.
I'm using following code from time to time if I do not hold direct access to Activity (for a reason or another);
new Handler(Looper.getMainLooper()).post(mYourUiThreadRunnable);
For Kotlin:
Handler(Looper.getMainLooper()).post {
/*My task*/
}
If you code in Kotlin you can use coroutine with Main dispatcher:
private fun runOnUiThread(block: () -> Unit) {
CoroutineScope(Dispatchers.Main).launch { block.invoke() }
}
Of-cause coroutines should added to your project as a dependency.
Sure. See Handler. You can give to your service a handler object and when service needs to run some Runnable task on UI thread just must call handler.post(some_runnable_task). This call. Can find a example in this link 4.Tutorial: Handler.
Your activity has to can bind to the service.
http://developer.android.com/guide/components/bound-services.html
Specifically, take a look at creating a Messenger on that page. The client activity can give a messenger object that responds to messages from the service, and once received, run whatever UI code is necessary on the UI thread using a handler.
DO NOT keep the activity's reference in the service. This can lead to all sorts of memory issues.
In Android, I have a thread that initializes a global variable. The thread starts when the activity starts. If the activity finishes before the thread initialized the global variable will the thread still run in the background to complete its job or it will be killed as the activity finishes?
The Activity finishing is part of the main execution/UI thread in android. When you spawn a new thread, and perform operations on that thread, it works as a separate entity from the main UI thread.
Hence, to answer your question - The thread will still run in the background to complete its job.
However, a word of caution. If within the run() method, you are using some objects that are part of the activity class that just got terminated, you can run into null pointer exceptions.