在android中,耗时的操作不能用ui线程来做,这会导致app卡顿,甚至出现卡死的现象。耗时的操作需要在子线程中完成。多线程从来都是头痛的事情,涉及到数据同步等,处理不好分分钟死给你看。所以需要一个逻辑清楚,结构简单,但运行可靠的模型。
AsyncTask是符合要求的模型,但在使用中发现它比较烦琐。如果有多个异步操作的话,还需要为每个操作定制化AsyncTask。反复开启AsyncTask也显得费力。
个人偏好的处理方式是使用HandlerThread。其中会用到的android的概念有:Handler,HandlerThread和Message。思路是,用HandlerThread开启一个异步线程,异步线程和ui线程之间用Message来通信,相应的操作在各自线程的Handler中来完成。以下是示例代码:
package hello.android;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.view.View;import android.widget.TextView;public class MainActivity extends Activity implements View.OnClickListener { private static final int UI_MSG0 = 0; private static final int THREAD_MSG0 = 0; private Handler mUiHandler; private Handler mThreadHandler; private HandlerThread mHandlerThread; private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.textView); mTextView.setOnClickListener(this); // mHandlerThread是开启的异步线程 mHandlerThread = new HandlerThread("thread0"); mHandlerThread.start(); mThreadHandler = new Handler(mHandlerThread.getLooper()) { @Override public void handleMessage(Message msg) { if (msg.what == THREAD_MSG0) { // 在异步线程中,接收ui线程发送过来的消息 // 并且提取需要的数据 int arg1 = msg.arg1; int arg2 = msg.arg2; // 在这里可以做复杂耗时的操作 // 这些操作都是在异步线程中完成 // 不会阻塞ui线程,自然不会造成卡死现象 arg1++; arg2++; // 复杂耗时操作的结果,会以消息的形式,发还给ui线程 // 这样做的好处是,共享数据以消息形式传递 // 两个异步线程没有共同操作的数据,不会因数据不同步而出错 mUiHandler.obtainMessage(UI_MSG0, arg1, arg2).sendToTarget(); } } }; mUiHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == UI_MSG0) { int arg1 = msg.arg1; int arg2 = msg.arg2; // 在ui线程中,处理异步线程返还的结果 mTextView.setText(arg1 + "," + arg2); } } }; } @Override protected void onStop() { // 结束异步线程 if (mHandlerThread != null) { mHandlerThread.quit(); } super.onStop(); } @Override public void onClick(View view) { int id = view.getId(); if (id == R.id.textView) { int arg1 = 0; int arg2 = 1; // 把复杂耗时的操作,以消息的形式发送给异步线程 // 同时包含需要用到的数据 mThreadHandler.obtainMessage(THREAD_MSG0, arg1, arg2).sendToTarget(); } }}