Hey here's an interesting question. I am using in my Android project, lots of sql operations with sqlite. For this matter, I am using thread pool in order of reusing the existing resources. The thread pool look's like this:
final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(NUMBER_OF_CORES*2,NUMBER_OF_CORES*2,1L, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(12,true),new PriorityThreadFactory(Process.THREAD_PRIORITY_BACKGROUND),new RejectedThread(context));
public class PriorityThreadFactory implements ThreadFactory {
private final int mThreadPriority;
public PriorityThreadFactory(int threadPriority) {
mThreadPriority = threadPriority;
}
#Override
public Thread newThread(final Runnable runnable) {
Runnable wrapperRunnable = new Runnable() {
#Override
public void run() {
try {
android.os.Process.setThreadPriority(mThreadPriority);
} catch (Throwable t) {
}
runnable.run();
}
};
return new Thread(wrapperRunnable);
}
}
public class RejectedThread implements RejectedExecutionHandler {
MyLogger myLogger;
public RejectedThread(Context context) {
this.myLogger=new MyLogger(RejectedThread.class.getSimpleName(), context);
}
#Override
public void rejectedExecution(Runnable worker, ThreadPoolExecutor executor) {
this.myLogger.info("Execution rejected for: "+worker.toString());
}
}
And also I am creating a new Runnable for every CRUD (Create-Read-Update-Delete) operation that I make in the database (being executed by the thread pool above). Here is the questions, beside the threadpool for sql operations, I would need one more thread pool for executing logger operations, to log system behavior for the rest of my functions that I make. Is there a way to prevent any crush/(insufficient resources) because I am using two or more thread pool executors (allocated separated, using in different purposes and never executing a thread pool executor on another thread pool executor) ?
I think that in general your idea is very good, but your implementation is a bit inefficient.
Try to answer these questions to yourself:
Why do you need two thread pools?
Do you REALLY need two thread pools?
Why do you set CORE size to NUMBER_OF_CORES*2?
Why do you set MAX size to NUMBER_OF_CORES*2?
Do you REALLY need to overwrite threads priorities?
In my experience, none of the above complications are really necessary.
For example, in all my apps I use a single instance of BackgroundThreadPoster class in order to offload work to background threads. The class is very simple:
/**
* A single instance of this class should be used whenever we need to post anything to a (random) background thread.
*/
public class BackgroundThreadPoster {
ExecutorService mExecutorService = Executors.newCachedThreadPool();
public void post(Runnable runnable) {
mExecutorService.execute(runnable);
}
}
Default pre-configured implementation returned by Executors.newCachedThreadPool() works like magic and I've never encountered any need to customize its parameters.
A full tutorial application that uses this approach can be found here: https://github.com/techyourchance/android_mvc_tutorial
Maybe this can work for you too?
Related
I've been writing android apps for some months now, and I'm at the point where I'm building an actual needed app.
As I want that to work nice and fast, I made a Workerthread to do all kinds of tasks in the background while the UI can...build up and work and stuff.
It's based on the Android Studio Drawer app blueprint.
In Main.onCreate I got my operator=new Operator(), which extends Thread.
Now, when loading a new Fragment, it sometimes calls MainActivity.operator.someMethod() (I made operator static so I can use it from anywhere), and after some time I realized, the only tasks actually running in background are those in the operators run() method and an Asynctask my login Fragment runs. Everything else the UI waits for to complete and therefore gets executed by the UI thread.
So I thought: no problem! My operator gets a handler which is built in run(), and I change those tasks:
public void run() {
Looper.prepare(); //Android crashed and said I had to call this
OpHandler = new Handler();
LoadLoginData();
[...Load up some Arrays with hardcoded stuff and compute for later use...]
}
public void LoadLoginData() {
OpHandler.post(LoadLoginDataRunnable);
}
private Runnable LoadLoginDataRunnable = new Runnable() {
#Override
public void run() {
if(sharedPreferences==null)
sharedPreferences= PreferenceManager.getDefaultSharedPreferences(context);
sessionID=sharedPreferences.getString("sessionID", null);
if(sessionID!=null) {
postenID = sharedPreferences.getString("postenID", PID_STANDARD);
postenName = sharedPreferences.getString("postenName", PID_STANDARD);
context.QuickToast(sessionID, postenName, postenID);
}
}
};
context is my MainActivity, I gave the operator a reference so I could send Toasts for Debugging.
But now, the Runnables seem to not run or complete, any Log.e or Log.d stuff doesn't arrive in the console.
After some googeling and stackoverflowing, everyone is just always explaining what the difference is between Handlers, Asynctask, and Threads. And the multitask examples always only show something like new Thread(new Runnable{run(task1)}).start times 3 with different tasks.
And so became my big question:
How to correctly, over a longer time (~lifecycle of the MainActivity), with different tasks, use a background thread?
Edit: to clarify, I would also like a direct solution to my special problem.
Edit 2: after reading nikis comment (thank you), the simple answer seems to be "use HandlerThread instead of thread". Will try that as soon as I get home.
Trying a HandlerThread now. It seems my OpHandler, initialized in run(), gets destroyed or something after run() has finished, not sure whats up here (this is btw another mystery of the kind I hoped would get answered here). I get a NullpointerException as soon as I try to use it after run() has finished.
Make your worker thread own a queue of tasks. In the run() method, just pop a task from the queue and execute it. If the queue is empty, wait for it to fill.
class Operator extends Thread
{
private Deque<Runnable> tasks;
private boolean hasToStop=false;
void run()
{
boolean stop=false;
while(!stop)
{
sychronized(this)
{
stop=hasToStop;
}
Runnable task=null;
synchronized(tasks)
{
if(!tasks.isEmpty())
task=tasks.poll();
}
if(task!=null)
task.run();
}
}
void addTask(Runnable task)
{
synchronized(tasks)
{
tasks.add(task);
}
}
public synchronized void stop()
{
hasToStop=true;
}
}
In android why should we use a asyntask and service, instead of using a new thread() and write the necessary background functionality?
I know that we should not run long running operations like downloading a file from server on the mainthread aka UI thread. And should use a asynctask or service.
But why cant we create a new thread() {which is eventually a new thread other than the main thread} and write necessarily long running operation in that thread.
why did google create the AsyncTask and Service without suggesting to use the regular New Thread()???
thanks in advance
edit1:
may be i wasn't clear in my question or not sure, if i am, even now. help me out.
i get it, the whole point starts from
Do not block the UI thread
Do not access the Android UI toolkit from outside the UI thread
why ?
1.how much can the UI thread handle ? how can we determine a breakpoint? how is a ANR point determined? can we track?
2. when a service component handles long running operations why can't a activity component handle?
Remember that if you do use a service, it still runs in your application's main thread by default, so you should still create a new thread within the service if it performs intensive or blocking operations
http://developer.android.com/guide/components/services.html
the above statement is from android documentation.
3.why cant a service start in a new thread straight away, if we are so concerned about main thread? don't get me wrong in question 3, i am trying to understand the advantage of starting the service in main thread. by default.
in the above statement , does it suggest the main thread's ability to start and handle a service's long running operation load? if so does it contradict with question 1.
Well let's look how you'd perform a simple task using a Thread.
The first step is to create a Thread using a Runnable. Something like this:
private void fetchResultsAsync() {
Runnable runner = new Runnable() {
#Override
public void run() {
List<String> results = fetchResultsFromWebServer();
}
};
new Thread(runner).run();
}
The thing is, we need to show the results so it would actually be more like this:
private void fetchResultsAsync() {
Runnable runner = new Runnable() {
#Override
public void run() {
List<String> results = fetchResultsFromWebServer();
workFinished(results);
}
};
new Thread(runner).run();
}
private void workFinished(List<String> results) {
// show the results on the UI
}
It looks good, but there's a problem; the callback method (workFinished) has to update the UI. If we do this from any non-main thread, there will be big problems. We need a thread-safe way to call that method, which is what Handlers are for. Let's also throw in a method for updating our progress, which is very common. The code would now look like this:
private final Handler myHandler = new Handler();
private void fetchResultsAsync() {
Runnable runner = new Runnable() {
#Override
public void run() {
List<String> results = fetchResultsFromWebServer();
workFinished(results);
}
};
new Thread(runner).run();
}
private void showProgress(int result) {
myHandler.post(new Runnable() {
#Override
public void run() {
// update a progress bar here
}
});
}
private void workFinished(final List<String> results) {
myHandler.post(new Runnable() {
#Override
public void run() {
// show the results on the UI
}
});
}
Compare this to the implementation using an AsyncTask:
private void fetchWithTask() {
new AsyncTask<Void, Integer, List<String>>() {
#Override
protected List<String> doInBackground(Void... params) {
return fetchResultsFromWebServer();
}
#Override
protected void onPostExecute(List<String> strings) {
// show the results on the UI
}
#Override
protected void onProgressUpdate(Integer... values) {
// update a progress bar here
}
}.execute();
}
It doesn't differ much by lines of code, but it's much more obvious what needs to happen and where. It protects you from nasty mistakes like forgetting to wrap UI-touching code in a Runnable that has to be posted to a UI-Thread-owned Handler.
Now imagine that you have several different types of small background tasks that need to be performed. It would be very easy to call the wrong showProgress or workFinished method from the wrong background Thread because you have to plug all those pieces together yourself.
There's also a very nasty bug lurking in the use of Handler's default constructor. If the containing class is first referenced by a non-UI thread during runtime, the Handler would belong to that Thread. AsyncTask hides always does things on the correct Thread. This is hard to catch!
At first blush AsyncTasks don't seem all that useful, but the callback plumbing is where they really pay off in spades.
"instead of using a new thread() and write the necessary background functionality?"
Why rewrite the background functionality? AsyncTask does it for you. As njk2 mentioned a Service is not really a fair comparison, though IntentService automatically creates a new thread for you in onHandleIntent().
edit: To answer your other questions, blocking the UI thread, will block all user interaction and the app will appear to "freeze". Definitely not something we want to do at all.
I'm developing a relatively small 2D game for Android right now. To process the collision detections as efficient as possible, I've created multiple threads working on the calculations:
Thread #1: Main handling of the frames, limiting them to X per second, handling the Bitmaps (rotate, draw...)
Thread #2: Calculate some collisions
Thread #3: Calculate other collisions
What I need is some sort of synchronization, but I am unsure of what's the best way to achieve this. I thought of something like this:
Thread #1:
public class Thread1 imlements Runnable {
public static ArrayList<Boolean> ResponseList = new ArrayList<Boolean>();
static {
ResponseList.add(0, false); // index 0 -> thread 1
ResponseList.add(1, false); // index 1 -> thread 2
}
public void run() {
boolean notFinished;
while(!isInterrupted() && isRunning) {
notFinished = true;
// do thread-business, canvas stuff, etc, draw
while(notFinished) {
notFinished = false;
for(boolean cur: ResponseList) {
if(!cur) notFinished = true;
}
// maybe sleep 10ms or something
}
}
}
}
And in the other calculation threads something like:
public class CalcThread implements Runnable {
private static final INDEX = 0;
public void run() {
while(isRunning) {
ResponseList.set(INDEX, false);
executeCalculations();
ResponseList.set(INDEX, true);
}
}
}
Or would it be faster (as this is what I'm concerned about) to use a Looper/Handler combination? Just read about this, but I'm not sure yet how to implement this. Would look deeper into this is this would be the more efficient method.
I don't know if it is going to be faster, but it will be more reliable for sure. For example, you are using ArrayList from multiple threads without serialization and ArrayList is not thread-safe
Handler is just one of the available mechanisms, I would recommend you to study java.util.concurrent - there is no point in reinventing the wheel, many synchronization primitives are already available. Perhaps Future would work for you
A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation.
while it is very convenient to use, from my understanding, AsyncTask has two important limitations:
doInBackground of any instances will share the same worker
thread, i.e. one long running AsyncTasks can block all others.
execute, onPostExecute and other "synchronizing" methods must/will always be executed on the UI-thread, i.e. not on the Thread, which wants to start the task.
I ran into trouble, when I tried to reuse some existing AsyncTasks in a background IntentService that are responsible for the client-server communication of my app. The tasks of the service would fight over time in the worker thread with those of the UI activities. Also they would force the service to fall back onto the UI-thread, although that service should perform its work quietly in the background.
How would I go about removing/circumventing these limitations? I basically want to achieve:
A framework that closely resembles AsyncTask (because I need to migrate a lot of critical code there).
Each instance of such a task should run its doInBackground on its own thread instead of a single worker thread for all instances.
Edit: Thx to VinceFR for pointing out this can be achieved by simply calling executeOnExecutor instead of execute.
The callbacks like onPostExecute should be called on the same thread that started the task by calling execute, which should not need to be the UI-thread.
I figure, I'm not the first person to require something like this. Therefore I wonder: Is there already some third-party library that can be recommended to accomplish this? If not, what would be a way to implement this?
Thanks in advance!
The solution looks like this:
All classes that spawn AsyncTasks that might interfere with each other get their own Executor like this one (make that elaborate as you like using thread pools etc.):
private Executor serviceExecutor = new Executor() {
public void execute(Runnable command) {
new Thread(command).start();
}
};
As pointed out by VinceFR you can run an AsyncTask on a given Executor by calling it like this (where payload are the parameters that you would regularly pass to a task):
task.executeOnExecutor(serviceExecutor, payload);
However, this breaks backwards-compatibility to Gingerbread and earlier. Also, if you want to support Honeycomb, you need to make sure, this call happens on the UI thread. Jelly Bean will take care of this automatically.
Now the trickier part: Keeping the service running on its own thread. As many things in Android this seems harder than it needs to be (or maybe I'm lacking some information here). You can't use an IntentService, because that will shut down automatically the first time an AsyncTask takes over and let's the onHandleIntent callback complete.
You need to setup your own thread and event loop on the service:
public class AsyncService extends Service {
private static final String TAG = AsyncService.class.getSimpleName();
private class LooperThread extends Thread {
public Handler threadHandler = null;
public void run() {
Looper.prepare();
this.threadHandler = new Handler();
Looper.loop();
}
}
private LooperThread serviceThread = null;
private Handler serviceThreadHandler = null;
#Override
// This happens on the UI thread
public void onCreate() {
super.onCreate();
}
#Override
// This happens on the UI thread
public int onStartCommand(Intent intent, int flags, int startId) {
this.serviceThread = new LooperThread();
this.serviceThread.start();
while(this.serviceThread.threadHandler == null) {
Log.d(TAG, "Waiting for service thread to start...");
}
this.serviceThreadHandler = this.serviceThread.threadHandler;
this.serviceThreadHandler.post(new Runnable() {
#Override
public void run() {
doTheFirstThingOnTheServiceThread();
}
});
return Service.START_STICKY;
}
// doTheFirstThingOnTheServiceThread
}
No you need to make sure that each time an AsyncTask returns to the UI thread, you end up in your service thread instead:
// This happens on the serviceThread
private void doTheFirstThingOnTheServiceThread() {
// do some stuff
// here we can reuse a class that performs some work on an AsyncTask
ExistingClassWithAsyncOperation someUsefullObject = new ExistingClassWithAsyncOperation();
// the existing class performs some work on an AsyncTask and reports back via an observer interface
someUsefullObject.setOnOperationCompleteListener(new OnOperationCompleteListener() {
#Override
// This happens on the UI thread (due to an ``AsyncTask`` in someUsefullObject ending)
public void onOperationComplete() {
serviceThreadHandler.post(new Runnable() {
#Override
public void run() {
doTheSecondThingOnTheServiceThread();
}
});
}
}
someUsefulObject.performOperation();
}
// This happens on the serviceThread
private void doTheSecondThingOnTheServiceThread() {
// continue working on the serviceThread
}
So, this works for me. I'd be delighted to see a simpler solution for this. Note that the solution requires the service to know that is will be called back by the ExistingClassWithAsyncOperation on the UI thread. I don't particularly like this dependency, but don't know how to do better right now. However, I don't have to rewrite a lot of existing classes that perform asynchronous operations using AsyncTask.
Is there such a thing as task queue on Android? I know that it can be written by hand but is there a ready to use library for that?
I'm not sure if there would be a library for this one, as Android already provides the high-level building blocks for what you're trying to achieve.
Handler
If I understood you correctly, you want to post tasks from any thread to be queued and executed one-by-one on a dedicated thread. This is very much what Android Handler is meant for.
Key traits of Handler, Looper and MessageQueue
A Handler is tied to a single Looper.
Each Looper has an associated MessageQueue
Handler uses a Looper underneath to enqueue and dequeue messages in a thread-safe manner into the Looper's MessageQueue.
Handler objects are inherently thread-safe and hence can be passed around to other threads safely.
You can have multiple Handler objects tied to a same Looper. This is useful if you want to process different kinds of messages using different Handlers. In this case, you are guaranteed that only one of the Handlers will process a Message/Runnable for a given Looper. The Looper takes care of dispatching the Message to the right Handler.
If you're already familiar with the Message Queue paradigm for communicating between 2 threads (or similar golang's buffered channel pattern), Handler is just a high level class which lets you use this pattern easily.
Example for using Handler to send/receive Messages, post Runnables
// BEGIN One-time Initialization
// Create a Handler thread
// This provides the looper for the Message Queue and
// will be processing all your messages (i.e. tasks).
handlerThread = new HandlerThread("SomeThreadName");
// Start the Handler Thread
// The thread will block (using the looper) until it
// receives a new message
handlerThread.start();
// Create a Message Handler which you can use to
// post and process messages
// The same Handler can also be used to post a Runnable which will get
// executed on handlerThread
handler = new CustomHandler(mHandlerThread.getLooper());
// END One-time Initialization
// Different ways to post a message to the Handler Thread
// These calls are thread-safe, can be called safely and
// concurrently from multiple threads without race conditions
handler.sendEmptyMessage(MESSAGE_ID_1);
handler.sendEmptyMessage(MESSAGE_ID_2);
handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1));
handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1));
handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1));
// Post a runnable on the Handler Thread
// This is thread-safe as well
// In fact all methods on the Handler class are thread-safe
handler.post(new Runnable() {
#Override
public void run() {
// Code to run on the Handler thread
}
});
// A skeleton implementation for CustomHandler
// NOTE: You can use the Handler class as-is without sub-classing it, if you
// intend to post just Runnables and NOT any messages
public class CustomHandler extends Handler {
public CustomHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message message) {
if (message != null) {
// Process the message
// The result can be sent back to the caller using a callback
// or alternatively, the caller could have passed a Handler
// argument, which the Handler Thread can post a message to
switch (message.what) {
case MESSAGE_ID_1:
// Some logic here
break;
case MESSAGE_ID_2:
// Some logic here
break;
case MESSAGE_ID_3:
// Some logic here
break;
case MESSAGE_ID_4:
// Some logic here
break;
case MESSAGE_ID_5:
// Some logic here
break;
// Add more message types here as required
}
}
}
}
// After you're done processing all messages and you
// want to exit the Handler Thread
// This will ensure that the queue does not accept any
// new messages, and all enqueued messages do get processed
handlerThread.quitSafely();
Deviations from the above example
Although I've used HandlerThread in the above example, it is not mandatory to use it. You can even use the Looper calls directly, i.e. Looper.prepare() and Looper.loop() to run your own message loop in a thread.
As already mentioned in the comments, you do not need to sub-class the stock Handler if you do not intend to handle any messages.
You can communicate between multiple threads easily by using a Handler for each thread that needs to receive the message.
There are methods in Handler to schedule message delivery and Runnable execution in the future as well.
Android's framework internally uses Handler extensively for managing component lifecycle events (onPause, onResume, etc.).
AsyncTask
AsyncTask is another alternative to scheduling tasks on a different thread. . I won't go into too much detail of its implementation, as the Android developer documentation already describes it in detail.
I usually use AsyncTasks for tasks that I know I'll use a background thread for a long time (easily >= 100 ms at least). Some examples which fall into this category I can think of are Binder IPC, RPC calls, Network calls, Background downloads, etc.
On the other hand, Handler is more tailored for situations focussed on processing more number of messages as quickly as possible. In other words avoid performing any blocking operation in handleMessage(). You can write lock-free code easily using Handler, it manages all the locking for you when enqueuing and dequeuing messages.
In fact AsyncTask can be used in combination with Handler by splitting the work into a fast part (taken care by Handler) and a slow part (taken care by AsyncTask).
PS: Although tangential to the question, if you're interested in the Message Queue paradigm; do take a look at LMAX Disruptor, which is a high performance inter-thread Message Queue library. Their design document explains pretty well, which parts of the Message Queue, need locking/atomic access.
I've also looked around for something like GCD for Android. While Handlers and AsyncTasks are awesome the beauty of GCD (in my humble opinion) is that you can dispatch a workload on a background thread to do the heavy lifting. When the execution is done it i easy to execute the UI updates on the UI thread.
Since I did not find anything me and my school mate decided to create one of our own.
You can find it at:
ICDispatch on github
Basically all you need to do is to declare an Application class that extends ICDispatchApplication instead of Application and when you want to dispatch something you just call on
App.executeOn(int queue, ICBlock block);
Example:
App.executeOn(ICDispatch.NORMAL, new ICBlock(){
public void run(){
//do stuff...
App.executeOn(ICDispatch.MAIN, new ICBlock(){
public void run(){
//post result to UI thread.
}
}
}
});
The worst part is that there will be a lot of indentation. In order to minimize indentation you could use lambda notation:
App.executeOn(ICDispatch.NORMAL, ()->{
//do stuff...
//do some more...
//then even more
App.executeOn(ICDispatch.MAIN,() -> {
//Post result on UI thread.
}
});
At the moment ICDispatch supports LOW, NORMAL, HIGH, MAIN and CONCURRENT queueing. Features will be added as they are implemented.
I don't know iOS so I'm not sure if it is the same but in Android you have the ScheduledThreadPoolExecutor
For anyone finding this thread now, there is a new framework available called Bolts. It has tasks and continuations and can wait on multiple tasks to finish, like GCD.
I take this sample from Telegram Code :
You can declare extended thread for this approach
public static volatile DispatchQueue globalQueue = new DispatchQueue("globalQueue");
the class is :
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import java.util.concurrent.CountDownLatch;
public class DispatchQueue extends Thread {
private volatile Handler handler = null;
private CountDownLatch syncLatch = new CountDownLatch(1);
public DispatchQueue(final String threadName) {
setName(threadName);
start();
}
private void sendMessage(Message msg, int delay) {
try {
syncLatch.await();
if (delay <= 0) {
handler.sendMessage(msg);
} else {
handler.sendMessageDelayed(msg, delay);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void cancelRunnable(Runnable runnable) {
try {
syncLatch.await();
handler.removeCallbacks(runnable);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void postRunnable(Runnable runnable) {
postRunnable(runnable, 0);
}
public void postRunnable(Runnable runnable, long delay) {
try {
syncLatch.await();
if (delay <= 0) {
handler.post(runnable);
} else {
handler.postDelayed(runnable, delay);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void cleanupQueue() {
try {
syncLatch.await();
handler.removeCallbacksAndMessages(null);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
#Override
public void run() {
Looper.prepare();
handler = new Handler();
syncLatch.countDown();
Looper.loop();
}
}
and the Caller :
globalQueue.postRunnable(new Runnable() {
#Override
public void run() {
/* do here what you want */
}
});
You should check Handler & Loopers
Handlers, by default (*), like dispatch_get_main_queue() and you can post any block (Runnable instance) of code. Same approach also acquired with Context.runOnUiThread() and View.post(Runnable)
(*) Default constructor of Handler inherits the current thread's Looper instance (RunLoop in iOS) and queues (via handlerInstace.post...() methods) Runnable instances on Looper.
For more advance usage. You can create your own Looper instance (be aware it is a bit tricky :)). Still this might be handy...
Also for more advance usage, Handlers are the best tools i come across on Android (and yes, i miss them on iOS) for messaging inside application (inter-process communication something i guess). They might be customized to handle posted messages, bla, bla...