Tuesday 3 April 2012

Threading in android

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:

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:
  1. 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.
  2. onPostExecute: This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.
  3. onPreExecute: This method is called before doInBackground method is called.
  4. onProgressUpdate: This method is invoked by calling publishProgress anytime from doInBackground call this method.
Overriding onPostExecute, onPreExecute and onProgressUpdate is optional.

Points to remember:

  1. 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.
  2. Methods onPostExecute, onPreExecute and onProgressUpdate should not be explicitly called.
  3. Task can be executed only once.

 

 



 

No comments:

Post a Comment