Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is better to use several AsyncTask or HandlerThread(Pipeline Thread)?

Tags:

java

android

Is it good approach to have one HandlerThread in app for making different time spending actions,like,for example,sorting or maybe even for working with web/file streams? What is better to use for such purposes: several AsyncTask's, several Threads or one HandlerThread like http://hi-android.info/src/android/webkit/WebViewWorker.java.html ?

like image 792
user1074896 Avatar asked Jan 18 '12 15:01

user1074896


People also ask

What is the difference between handler vs AsyncTask vs thread?

AsyncTask are similar, in fact, they make use of Handler , but doesn't run in the UI thread, so it's good for fetching data, for instance fetching web services. Later you can interact with the UI. Thread however can't interact with the UI, provide more "basic" threading and you miss all the abstractions of AsyncTask .

What is the difference between handler and Handlerthread?

Threads are generic processing tasks that can do most things, but one thing they cannot do is update the UI. Handlers on the other hand are background threads that allow you to communicate with the UI thread (update the UI).

What are thread Handlers?

A Handler is a component that can be attached to a thread and then made to perform some action on that thread via simple messages or Runnable tasks. It works in conjunction with another component, Looper , which is in charge of message processing in a particular thread.


2 Answers

You must delegate time consuming operation (network, database access, ...) to some type of worker threads. It is not acceptable to block the main (UI) thread.

AsyncTask is a high level object. It takes care of the thread handling and inter-thread communications for you, using an internal Handler and an Executor. It has been designed for the (very) common case of doing something in the background and pushing the result to the UI.

Using Handler and HandlerThread (or event Thread) directly gives you more flexibility, at the cost of a more complex code, and some subtle pitfalls (e.g. How to Leak a Context: Handlers & Inner Classes).

One choice you have make is to execute the tasks serially or in parallel. A HandlerThread would serialize them. For AsyncTask it depends on the Android version (but this can be overridden). Creating a Thread every time may result in an excessive number of concurrent threads.

like image 130
bwt Avatar answered Sep 21 '22 10:09

bwt


Short answer, they are all good because you aren't locking the UI.

Longer answer, Mostly comes down to preference. The solution I use is a combination of basic threads and a handler. Since a basic thread does not run on the main UI thread, often when one completes you need to report back or update settings. This is when I use a handler and a set of easy to read keys. Thus allowing me to access any view and change it as needed. Remember, it is unwise to declare and keep global references to Views, allocate and use as needed and discard when done.

private static final int SET_LOADING    = 0;
private static final int SET_TEXT       = 1;


private Handler mEventHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        // if stmts||switch - personal preference
        if(msg.what     == SET_LOADING ){

            setLoading(((Boolean) msg.obj));

        }else if(msg.what == SET_TEXT){

            setText(msg.arg1, (String) msg.obj);

        }
        super.handleMessage(msg);
    }   
}

/**
 * set the text of a textbox
 * @param id int - R.id.{...}
 * @param text String
 */
private void setText(int id, String text){
    TextView t = ((TextView) findViewById(id));
    if(t != null){
        t.setText(text);
    }
}


/**
 * is the UI currently loading something? lock controls
 * @param isLoading boolean
 */
private void setLoading(boolean isLoading){
    mIsLoading = isLoading;
    if(isLoading){
        (SomeSpinningProgressBar).setVisibility(View.VISIBLE);
    }else{
        (SomeSpinningProgressBar).setVisibility(View.INVISIBLE);
    }
}



public void onClick(View v) {
    /**
    * some button that triggers a database connection
    */
    if( v.getId() == R.id.some_button ) {

        /** basic thread */
        new Thread(new Runnable() {
                public void run() { 
                    if(this.hasWebConnection()){
                        /** tell the UI thread to start loading */
                        mEventHandler.sendMessage(
                            mEventHandler.obtainMessage(SET_LOADING, 0, 0, true));

                        // do work...

                        if(someErrorOccuredBoolean){
                            /** report to user of an error */
                            mEventHandler.sendMessage(
                                mEventHandler.obtainMessage(SET_TEXT, R.id.some_textview, 0, "There was an error!"));
                        }
                        /** tell the UI thread to stop loading */
                        mEventHandler.sendMessage(
                                mEventHandler.obtainMessage(SET_LOADING, 0, 0, false));
                    }else{
                        mEventHandler.obtainMessage(SET_TEXT, R.id.some_textview, 0, "No internet found!!"));
                    }
                }
            }
        );      
    }
}
like image 27
BajaBob Avatar answered Sep 22 '22 10:09

BajaBob