在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();
}
}
}