android - 我正确使用 AsyncTask 吗?
问题描述
我正在阅读“Professional Android”一书,他们对以下内容说AsyncTask
:
需要注意的是,异步任务对其运行的组件的生命周期没有内置的理解。这意味着,如果您正在创建
Async Task
in anActivity
,为避免内存泄漏,您应该将其定义为静态(并确保它不持有对 anActivity
或其的强引用Views
)。
为了测试Async Task
,我编写了以下代码,它应该在后台反转一个字符串,并通过更新一个TextView
. 我在这里使用强参考吗?
package com.example.leo.test01;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private TextView textView;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text_view_reversed_string);
new reverseStringAsync(textView).execute("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}
private static class reverseStringAsync extends AsyncTask<String, String, String> {
private TextView textView;
reverseStringAsync(TextView textView) {
this.textView = textView;
}
@Override
protected void onPreExecute() {
Log.d(TAG, "onPreExecute()");
textView.setText("");
}
@Override
protected String doInBackground(String... strings) {
Log.d(TAG, "doInBackground()");
int n = strings[0].length();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 1; i <= n; i++) {
stringBuilder.append(strings[0].charAt(n - i));
publishProgress(stringBuilder.toString());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return stringBuilder.toString();
}
@Override
protected void onProgressUpdate(String... values) {
Log.d(TAG, "onProgressUpdate()");
textView.setText(values[0]);
}
@Override
protected void onPostExecute(String s) {
Log.d(TAG, "onPostExecute()");
textView.setText(s);
}
}
}
解决方案
你真的不应该在这样的 AsyncTask 上睡觉。原因 - 所有 AsyncTask 共享同一个线程(除非您调用 executeOnExecutor)。这意味着如果一个任务正在运行,系统中的其他 AsyncTask 将在其完成之前运行。因此,AsyncTask 应该非常快速且独立。每次一秒钟要睡 N 次的东西不应该是异步任务。
对于这样的事情,正确的答案可能只是将延迟消息发布到 Handler 并在每次延迟时在 UI 线程上运行它。
对于实际上在做 CPU 密集型工作但需要像这样休眠的东西,请使用线程。
推荐阅读
- reactjs - ClassNames 与服务器解释不匹配
- java - 根据 HashMap 值/键更新列表元素
- c# - 如何为双引号选项内的文件路径编写ffmpeg windows命令
- php - DKMI 使用 phpmailer 无效
- spring - 多对多关系在 Spring JPA、Kotlin 中不存在
- c++ - 使用 GetComputerObjectNameW win API 时出现编译错误
- excel - 用户表单清除功能似乎不起作用
- angular - 离子“空白”页面中的d3js网络图
- android - 如何创建带有圆角/角的框架的复杂矩形位图?
- ios - 尽管 NSPhotoLibraryUsageDescription 应用程序崩溃