Threading Example in Android

Threading Example in Android

This is a nice tutorial:

http://android-developers.blogspot.de/2009/05/painless-threading.html

Or this for the UI thread:

http://developer.android.com/guide/faq/commontasks.html#threading

Or here a very practical one:

http://www.androidacademy.com/1-tutorials/43-hands-on/115-threading-with-android-part1

and another one about procceses and threads

http://developer.android.com/guide/components/processes-and-threads.html

Java (Android) multi-threading process

Observation:

After creating and observing a independent java application (logs) using same code, I came to know the followings:

  • Somehow android OS architecture and/or processor is limiting the number of threads.
  • LinkedBlockingQueue holds tasks before they executed, so if we have a long queue later threads in queue will have to wait more.
  • Increase/Dynamic corePoolSize and maxPoolSize is doing the same, they added threads in queue
  • Application uses 4-6% of CPU so we can't say CPU is overloading or utilizing full application resources but when application goes into background (GUI or other related OS and/or application based threads may stop or interrupted) CPU uses drops to 0-3%.

Solution:

For 50 iterations and 10 inner creates 500 threads now i did two things:

  • Increase Thread.sleep(millis) time with some calculation involves.
  • Decrease number of threads for each iteration. I was creating 10 threads now Math.ceil((double) 10 / 3) = 3 so we have 3 sequential PingUtils.executePingRequest(pingRequest) for each thread i.e. 3 * 3 = 9 remains 1 so we will create a separate thread for last request. For each iteration instead of creating 10 threads now i am creating 4 threads.
  • Using this approach now i have 200 threads instead of 500 which solves the issue.

Multi Threading in Android

Try to use an AsyncTask like this:

   public class MyTask extends AsyncTask<Void, Void, Void> {

private volatile boolean running = true;

@Override
protected void onCancelled() {
running = false;
}

@Override
protected Void doInBackground(Void... params) {

while (running) {
// download
}
return null;
}

}

Activity:

   @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
task = new MyTask();
task.execute();
}

@Override
public void onDestroy() {
super.onDestroy();
if (task != null) task.cancel(true);
}

But for me the easiest way to download and display images is using Picasso.

Its that simple:

Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)

How to make a new thread, Android Studio?

I have encountered the same problem.

The solution for my issue was to create 3 runnables and start them in onCreate() Method.

It looks like that:

Thread thread = new Thread(runnable);
thread.start();

In order to create runnable "object" just do the following:

Runnable runnable = new Runnable(){
public void run() {
//some code here
}
};

If you want some delayed action, you can work with post delayed in runnable interface (beware, postDelayed() would just repeat the whole runnable. You can avoid that, by adding some conditions)

Runnable runnable = new Runnable(){
public void run() {
//some code here
handler.postDelayed(this, 1000);
}
};

If you want to update GUI, you should invoke following command inside your runnable:

handler.post(new Runnable() {
@Override
public void run () {
// upate textFields, images etc...

}
});

P.S. If you have multiple threads and they must be started at different time you can start them from Runnables.

Some pages that can be helpful:

new Runnable() but no new thread?

What's the difference between Thread start() and Runnable run()

How to run a Runnable thread in Android at defined intervals?

When to use handler.post() & when to new Thread()

how to use handler on android concurrently?

Handler can't work in an asynchronous way in the same thread.

A handler allows you to send and process Messages and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue. The MessageQueue is a queue that has a list of tasks (messages, runnable) that will be executed in a certain thread. When you create a new handler, it is bound to the thread/message queue of the thread that is creating it — from that point on, it will deliver messages and runnables to that message queue and executes them as they come out of the message queue. The looper is responsible for keeping the thread alive. It is a kind of worker that serves a MessageQueue for the current thread. Looper loops through a message queue and sends messages to corresponding threads to process.

see this image for a clear concept

When a handler is created, it can get a Looper object in the constructor, which indicates which thread the handler is attached to. So attaching handlers to the different threads can make them Asynchronous. Here you are posting the runnables in same thread MessageQueue with same time delay so it will execute sequentially.

To know more knowledge about Handler, Thread, Looper, and Message Queue you can read this blog

How to run a Runnable thread in Android at defined intervals?

The simple fix to your example is :

handler = new Handler();

final Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
};

handler.postDelayed(r, 1000);

Or we can use normal thread for example (with original Runner) :

Thread thread = new Thread() {
@Override
public void run() {
try {
while(true) {
sleep(1000);
handler.post(this);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};

thread.start();

You may consider your runnable object just as a command that can be sent to the message queue for execution, and handler as just a helper object used to send that command.

More details are here http://developer.android.com/reference/android/os/Handler.html

How to run task using Thread in Background

please check the sample -

 public class EventHandlerImplementation extends EventHandler {
private EventHandlerImplementation(EventRunner runner) {
super(runner);
}

@Override
public void processEvent(InnerEvent event) {
getUITaskDispatcher().asyncDispatch(() -> {
// do your stuff here
});
}
}

Difficulty in understanding complex multi threading in Android app

First of All,

The runnable part in your followed example is just for the sake of animating realtime data updating, You can choose to call appendData() without creating a new runnable. You need to call appendData() from main thread though.

Secondly,

You can call the appendData() function directly from your onEventMainThread function, but as you pointed out that this approach sometimes hangs the UI, One possible reason for this behaviour is that you are probably posting events too frequently, Updating UI too frequently would ultimately hang the UI at some point. You can do the following to avoid this:

Updating UI too frequently might also hang the UI,
Here's a Solution:

Put some logic in ProcessThread to save last sent event time and compare it before sending a new one and if the difference is less than 1 second than save it for sending later and when the next computation is done, compare the time again, if it is greater than 1 second now, than send the events in array or may be send just the latest event, as the latest computation can represent the latest state of graph right?

Hope that helps!

Edit: (in response to Comment 1 & 2)

I am not sure what you tried may be posting your updated code would give a better idea. but I think you tried to implement time check functionality in onEventMainThread or in PlotsRun runnable, is that correct? If yes than I am afraid that wouldn't be of much of help for you. What you need to do instead is to implement this time checking check inside ProcessThread and only post new event if threshold time is reached. For following reasons:

1- EventBus on the backend automatically creates a new runnable and calls onEventMainThread in it. So, handling time check inside ProcessThread would spawn less unwanted runnables into the memory which would result in less memory consumption.

2- Also no need to maintain queue and spawn new runnables, just update the data in onEventMainThread.

Below is a bare minimum code to provide proof of concept only, You would need to update it according to your needs:

ProcessThread class:

private class ProcessThread extends Thread{
private static final long TIME_THRESHOLD = 100; //100 MS but can change as desired
private long lastSentTime = 0;
private float value = 0f;
private ReadingsUpdateData updater = new ReadingsUpdateData(values);
public void run() {
while(true) {
if (System.currentTimeMillis() - lastSentTime < TIME_THRESHOLD) {
try {
Thread.sleep(TIME_THRESHOLD - (System.currentTimeMillis() - lastSentTime));
} catch (InterruptedException e) {}
}

value = getRandom();
updater.setData(value);
EventBus.getDefault().post(updater);
lastSentTime = System.currentTimeMillis();
}
}
}

onEventMainThread method:

public void onEventMainThread(ReadingsUpdateData data){
mSeries1.appendData(new DataPoint(counter, data), true, 100);
counter++;
}


Related Topics



Leave a reply



Submit