android中实现异步机制的方法有两种,Handler和AsyncTask。
Handler在使用时,需要新开辟一个线程,在任务完成以后,通过sendmessage()等方法通知UI线程进行界面更新。
相比起Handler,AsyncTask显得更加简单,内部封装了线程池、线程和Handler。
我们通常是继承AsyncTask并重写其中的方法:
public abstract class AsyncTask<Params, Progress, Result> {
三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。
分别是在:
@WorkerThread
protected abstract Result doInBackground(Params... params);
@MainThread
protected void onProgressUpdate(Progress... values) {
中用到了Params和progress,Result则是用作返回值。
相关方法和执行过程:
继承AsyncTask,必须重写doInBackground()方法;
在使用AsyncTask时要注意以下事项:
下面写一个例子以免以后忘记,例子用于打印一段话的长度,在DoInBackground中调用Thread.sleep(),模拟耗时操作:
<string name="async_task_text_1">一个简单小例子,主要功能是,统计本段话的所有字符的长度。
为了模拟耗时操作,在doInBackground方法里让Thread睡一会。</string>
public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextView1;
private ProgressBar mProgressBar;
private TextView mTextView2;
private Button mButton;
private Button mButton2;
private MyTask mMyTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task);
initView();
initData();
}
private void initView() {
mTextView1 = findViewById(R.id.textView1);
mTextView2 = findViewById(R.id.textView2);
mProgressBar = findViewById(R.id.progressBar);
mButton = findViewById(R.id.button);
mButton2 = findViewById(R.id.button2);
mButton.setOnClickListener(this);
mButton2.setOnClickListener(this);
}
private void initData() {
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
mMyTask = new MyTask(this);
mMyTask.execute(getResources().getString(R.string.async_task_text_1));
break;
case R.id.button2:
if (mMyTask != null) {
mMyTask.cancel(true);
mMyTask = null;
}
break;
default:
break;
}
}
static class MyTask extends AsyncTask<String, Float, Long> {
WeakReference<AsyncTaskActivity> mWeakReference;
int length;
public MyTask(AsyncTaskActivity activity) {
mWeakReference = new WeakReference<>(activity);
}
/**
* 执行线程任务前的操作
*/
@Override
protected void onPreExecute() {
AsyncTaskActivity activity = mWeakReference.get();
length = activity.getApplicationContext().getResources().getString(R.string.async_task_text_1).length();
activity.mTextView1.setText(activity.getApplicationContext().getResources().getString(R.string.async_task_text_1));
activity.mProgressBar.setMax(length);
}
@Override
protected Long doInBackground(String... strings) {
for (int i = 0; i < length; i++) {
if (!isCancelled()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
break;
}
publishProgress((float) i);
}
return (long) length;
}
@Override
protected void onProgressUpdate(Float... values) {
AsyncTaskActivity activity = mWeakReference.get();
if (activity == null || activity.isFinishing()) {
return;
}
activity.mProgressBar.setProgress(Math.round(values[0]));
activity.mTextView2.setText("onProgress = " + values[0] * 1.0f / length);
}
@Override
protected void onPostExecute(Long aLong) {
AsyncTaskActivity activity = mWeakReference.get();
if (activity == null || activity.isFinishing()) {
return;
}
activity.mProgressBar.setProgress(activity.mProgressBar.getMax());
activity.mTextView2.setText("完成了,这段话一共有 " + aLong + " 个字。");
}
@Override
protected void onCancelled(Long aLong) {
AsyncTaskActivity activity = mWeakReference.get();
if (activity == null || activity.isFinishing()) {
return;
}
activity.mTextView2.setText("已取消");
}
@Override
protected void onCancelled() {
super.onCancelled();
}
}
}
这里使用静态内部类+外部类的弱引用方式避免内存泄漏。
因篇幅问题不能全部显示,请点此查看更多更全内容