Android 从工作线程调用AsyncTask,但应用程序未崩溃。为什么?
我读到,必须在UI线程上调用执行的线程规则(Params…)部分。但是当我检查这个演示时,它工作得很好。有人能帮我找出我在这里遗漏了什么吗Android 从工作线程调用AsyncTask,但应用程序未崩溃。为什么?,android,android-asynctask,Android,Android Asynctask,我读到,必须在UI线程上调用执行的线程规则(Params…)部分。但是当我检查这个演示时,它工作得很好。有人能帮我找出我在这里遗漏了什么吗 public class MainActivity extends AppCompatActivity { public static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) {
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
new PublicTask().execute();
}
}).start();
}
});
}
public class PublicTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.i(TAG, "onPreExecute called");
}
@Override
protected Void doInBackground(Void... voids) {
Log.i(TAG, "doInBackground called");
return null;
}
}
}
它不会崩溃,因为您没有尝试从
onPreExecute()
更新UI。尝试从onPreExecute()
更改UI中的某些内容,您的应用程序应该会很好地崩溃。在JellyBean版本之前,无论何时创建AsyncTask对象,都会在创建AsyncTask对象的线程上实例化一个名为InternalHandler的处理程序(此处理程序负责将结果从后台线程传递到AsyncTask中的主线程)并且我们知道,处理程序对象只能在具有Looper的线程上实例化,因此有必要在主线程中实例化AsyncTask
从JellyBean版本开始,您不必担心它,因为InternalHandler是通过android系统传递主线程循环器自动实例化的,如源代码所示
public InternalHandler() {
super(Looper.getMainLooper());
}
因此,即使您在后台线程中创建AsyncTask对象,它也不会给出任何异常,onPostExecute和onPreExecute将在主线程上正常运行,并且可以更新UI safefly我想说的是,这是因为您没有对UI做任何更改。尝试更改UI的某些内容,大多数情况下肯定会崩溃。我不是在测试我现在还没有,但在我的脑海中,我假设AsyncTask的形式是假定调用时使用的循环器是主循环器。这是不正确的。即使从后台线程调用AsyncTask,它也可以正常工作,并且onPostExecute仍将在UI上运行thread@HasifSeyd-你确定吗?文件中明确指出,
AsyncTask
实例必须在UI线程上创建。自JellyBean以来唯一发生变化的是,AsyncTask
类本身会自动加载到UI线程上(这也是一项要求)。我想唯一明确的答案是测试它(无可否认,我最近没有这样做).但如果你的答案是正确的,那么文档中仍然列出这些要求就很奇怪了。
public InternalHandler() {
super(Looper.getMainLooper());
}