Android多线程之HandlerThread

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kikitious_Du/article/details/78846327

HandlerThread简介


HandlerThread继承自Thread,所以本质上HandlerThread是一个线程类。

HandlerThread是一种可以使用Handler的Thread。

HandlerThread在内部创建了消息队列,外界通过Handler的消息方式来通知HandlerThread执行一个具体的任务。


HandlerThread使用


① 创建HandlerThread对象

        HandlerThread thread = new HandlerThread("my-handler-thread");

② 启动线程

        thread.start();

③ 创建Handler对象,传入HandlerThread对象所在线程的Looper对象

        Handler downloadHandler = new Handler(thread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                //执行具体的耗时任务,如加载网络图片等
                
                //通知主线程刷新UI
                mUIHandler.sendMessage(message);
            }
        };

④ Handler对象发送Message或者Runnable

        downloadHandler.sendEmptyMessageDelayed(100, 1000);

全部代码如下:

public class MyHandlerThreadActivity extends BaseActivity {
    private static final String TAG = "MyHandlerThreadActivity";

    private String url = "https://img-blog.csdn.net/20160903083245762";
    private ImageView imageView;
    private Handler uiHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            imageView.setImageBitmap((Bitmap) msg.obj);
        }
    };
    private HandlerThread thread;
    private Handler downloadHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler_thread);
        Log.i(TAG, "Thread.currentThread().getName() = " + Thread.currentThread().getName());

        findView();

        initTask();
    }

    private void findView() {
        imageView = (ImageView) findViewById(R.id.image);
    }

    @Override
    protected void onResume() {
        super.onResume();
        downloadHandler.sendEmptyMessageDelayed(100, 1000);
    }

    private void initTask() {
        thread = new HandlerThread("my-handler-thread");
        thread.start();
        Log.i(TAG, "thread.getName() = " + thread.getName());

        //加载网络图片,耗时任务
        downloadHandler = new Handler(thread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                //加载网络图片,耗时任务
                Bitmap bitmap = downloadUrlBitmap(url);
                Message message = Message.obtain();
                message.what = msg.what;
                message.obj = bitmap;
                uiHandler.sendMessage(message);
            }
        };

    }

    private Bitmap downloadUrlBitmap(String urlString) {
        HttpURLConnection conn = null;
        BufferedInputStream in = null;
        Bitmap bitmap = null;
        try {
            URL url = new URL(urlString);
            conn = (HttpURLConnection) url.openConnection();
            InputStream inputStream = conn.getInputStream();
            in = new BufferedInputStream(inputStream, 8 * 1024);
            bitmap = BitmapFactory.decodeStream(in);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bitmap;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        thread.quit();
    }
}

HandlerThread源码

    public class HandlerThread extends Thread {
        int mPriority;
        int mTid = -1;
        Looper mLooper;//当前线程持有的Looper对象
    
        public HandlerThread(String name) {
            super(name);
            mPriority = Process.THREAD_PRIORITY_DEFAULT;
        }
    
        //name线程名称,priority线程优先级
        public HandlerThread(String name, int priority) {
            super(name);
            mPriority = priority;
        }
    
        protected void onLooperPrepared() {
        }
    
        //创建HandlerThread的对象之后,必须先调用start()方法,即会先调用run()方法
        //Looper对象创建后,第③步中将这个Looper对象传入Handler对象中
        //可以保证此Handler对象中的handleMessage方法执行在异步线程
        @Override
        public void run() {
            mTid = Process.myTid();
            Looper.prepare();//创建Looper对象
            synchronized (this) {
                mLooper = Looper.myLooper();
                notifyAll();//唤醒机制,见下面的getLooper方法
            }
            Process.setThreadPriority(mPriority);
            onLooperPrepared();
            Looper.loop();
            mTid = -1;
        }
    
        //第③步,thread.getLooper()时,在主线程中调用此方法
        //而Looper对象的创建是在子线程中
        //所以,我们无法保障在调用getLooper方法时Looper已经被创建
        //故,只有当线程创建成功&&Looper对象创建成功以后,这里才能获得mLooper的值
        public Looper getLooper() {
            if (!isAlive()) {//先判断当前线程是否启动,没启动直接返回null
                return null;
            }
    
            // If the thread has been started, wait until the looper has been created.
            // 当线程创建成功后,必须等到Looper对象创建成功以后,这里才能获得mLooper的值
            synchronized (this) {
                while (isAlive() && mLooper == null) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
            return mLooper;
        }
    
        //调用Looper的quit方法,最终执行removeAllMessagesLocked()方法
        public boolean quit() {
            Looper looper = getLooper();
            if (looper != null) {
                looper.quit();
                return true;
            }
            return false;
        }
    
        //调用Looper的quitSafely方法,最终执行removeAllFutureMessagesLocked()方法
        public boolean quitSafely() {
            Looper looper = getLooper();
            if (looper != null) {
                looper.quitSafely();
                return true;
            }
            return false;
        }
    
        public int getThreadId() {
            return mTid;
        }
    }

    //MessageQueue.java中的quit方法
    void quit(boolean safe) {
        if (!mQuitAllowed) {
            throw new IllegalStateException("Main thread not allowed to quit.");
        }

        synchronized (this) {
            if (mQuitting) {
                return;
            }
            mQuitting = true;

            if (safe) {
                //只会清空MessageQueue消息池中所有的延迟消息,
                //并将消息池中所有的非延迟消息派发出去让Handler去处理完成后才停止Looper循环
                removeAllFutureMessagesLocked();
            } else {
                //把MessageQueue消息池中所有的消息全部清空,
                //无论是延迟消息(延迟消息是指通过sendMessageDelayed或通过postDelayed等方法发送)还是非延迟消息
                removeAllMessagesLocked();
            }

            // We can assume mPtr != 0 because mQuitting was previously false.
            nativeWake(mPtr);
        }
    }



参考链接:

http://blog.csdn.net/lmj623565791/article/details/47079737/

http://blog.csdn.net/javazejian/article/details/52426353

猜你喜欢

转载自blog.csdn.net/Kikitious_Du/article/details/78846327
今日推荐