Multi threading concept is important in android.It help to increase the utilization of the processor. Android provide multi threading concept to perform the time consuming task in the background thread with coordination with the UI thread to update the UI.
Handlers
Async. Tasks are the methods provided by the thread
Handlers
Handlers is a class,that process the messages and Runnable objects associated with the current thread MessageQueue.
Using Messages:
a) first you create a handler object associated with call back method to handle the received messages.
b)From the background thread you need to send the message to the handler.
Here is a code for one activity, which display the same message for a number of time.
package com.ann;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
public class ThreadmsgActivity extends Activity {
TextView txt;
Handler handler=new Handler(){
public void handleMessage(Message msg){
txt.setText(txt.getText()+"Item "+System.getProperty("line.separator"));
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
}
public void onStart(){
super.onStart();
Thread thread=new Thread(new Runnable(){
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000);
// send message to the handler with the current message handler
handler.sendMessage(handler.obtainMessage());
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});
thread.start();
}
}
Each second a new line is written:
When we want send message that hold data which change data each time change,the answer is to use Message.setData(Bundle bundle) method by creating a Bundle object and adding the data to it like this:
package com.ann;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
public class ThreadmsgActivity extends Activity {
TextView txt;
Handler handler=new Handler(){
public void handleMessage(Message msg){
Bundle b=msg.getData();
String str=b.getString("My key");
txt.setText(txt.getText() + "Item " +str
+System.getProperty("line.separator"));
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
}
public void onStart(){
super.onStart();
Thread thread=new Thread(new Runnable(){
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000);
Message msg=new Message();
Bundle b=new Bundle();
b.putString("My key","My value"+String.valueOf(i));
msg.setData(b);
// send message to the handler with the current message handler
handler.sendMessage(msg);
// send message to the handler with the current message handler
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});
thread.start();
}
}
We put a string to the bundle and send a message with that bundle. in the handler method we receive the bundle and get the value with the predefined key.
After executing that code the text view would look like this:
Using Runnable
The another way to use handler is to pass them a Runnable by using the
method handle.post().
package com.ann;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
public class ThreadrunnableActivity extends Activity {
TextView txt;
// our handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
txt.setText(txt.getText() + "Item " + System.getProperty("line.separator"));
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
}
@Override
protected void onStart() {
super.onStart();
// create a new thread
Runnable r=new Runnable() {
@Override
public void run() {
txt.setText("Using Runnable");
}
};
handler.post(r);
}}
Here giving the comparison of the Runnable & normal Thread
The simple Runnable to your example is:
Async. Tasks
package com.ann;
As seen class AscyncTaskActivity extends AsyncTask and implements 4 methods:
Handlers
Async. Tasks are the methods provided by the thread
Handlers
Handlers is a class,that process the messages and Runnable objects associated with the current thread MessageQueue.
Using Messages:
a) first you create a handler object associated with call back method to handle the received messages.
b)From the background thread you need to send the message to the handler.
Here is a code for one activity, which display the same message for a number of time.
package com.ann;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
public class ThreadmsgActivity extends Activity {
TextView txt;
Handler handler=new Handler(){
public void handleMessage(Message msg){
txt.setText(txt.getText()+"Item "+System.getProperty("line.separator"));
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
}
public void onStart(){
super.onStart();
Thread thread=new Thread(new Runnable(){
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000);
// send message to the handler with the current message handler
handler.sendMessage(handler.obtainMessage());
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});
thread.start();
}
}
Each second a new line is written:
When we want send message that hold data which change data each time change,the answer is to use Message.setData(Bundle bundle) method by creating a Bundle object and adding the data to it like this:
package com.ann;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
public class ThreadmsgActivity extends Activity {
TextView txt;
Handler handler=new Handler(){
public void handleMessage(Message msg){
Bundle b=msg.getData();
String str=b.getString("My key");
txt.setText(txt.getText() + "Item " +str
+System.getProperty("line.separator"));
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
}
public void onStart(){
super.onStart();
Thread thread=new Thread(new Runnable(){
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000);
Message msg=new Message();
Bundle b=new Bundle();
b.putString("My key","My value"+String.valueOf(i));
msg.setData(b);
// send message to the handler with the current message handler
handler.sendMessage(msg);
// send message to the handler with the current message handler
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});
thread.start();
}
}
We put a string to the bundle and send a message with that bundle. in the handler method we receive the bundle and get the value with the predefined key.
After executing that code the text view would look like this:
Using Runnable
The another way to use handler is to pass them a Runnable by using the
method handle.post().
package com.ann;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
public class ThreadrunnableActivity extends Activity {
TextView txt;
// our handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
txt.setText(txt.getText() + "Item " + System.getProperty("line.separator"));
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
}
@Override
protected void onStart() {
super.onStart();
// create a new thread
Runnable r=new Runnable() {
@Override
public void run() {
txt.setText("Using Runnable");
}
};
handler.post(r);
}}
Here giving the comparison of the Runnable & normal Thread
The simple Runnable to your example is:
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(r);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
Async. Tasks
Android Async Task takes cares of thread management and is the recommended mechanism for performing long running operations.
Let us look a sample class AscyncTaskActivity,which extends Async Tasks bellow:
package com.ann;
import android.os.AsyncTask;
import android.view.View;
public class AscyncTaskActivity extends AsyncTask<String, Void, String> {
/** Called when the activity is first created. */
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
public void onClick(View v) {
new AscyncTaskActivity().execute("");
}
}
As seen class AscyncTaskActivity extends AsyncTask and implements 4 methods:- doInBackground: Code performing long running operation goes in this method. When onClick method is executed on click of button, it calls execute method which accepts parameters and automatically calls doInBackground method with the parameters passed.
- onPostExecute: This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.
- onPreExecute: This method is called before doInBackground method is called.
- onProgressUpdate: This method is invoked by calling publishProgress anytime from doInBackground call this method.
Points to remember:
- Instance of Async Task needs to be created in UI thread. As shown in onClick method a new instance of LongOperation is created there. Also execute method with parameters should be called from UI thread.
- Methods onPostExecute, onPreExecute and onProgressUpdate should not be explicitly called.
- Task can be executed only once.
No comments:
Post a Comment