我是Android的新手,我的简单应用程序出了问题。 我使用非常简单的计数器使用AsyncTask。
当我运行应用程序并启动计数器时,它计数到10,然后不是打印“完成!”应用程序只是粉碎,我不知道为什么。这是我的代码。 (该活动有3个按钮来创建,启动和取消任务)。
public class AsyncTaskActivity extends AppCompatActivity {
AsyncTask myAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task);
}
public static void startActivity(Context context){
Intent intent = new Intent(context, AsyncTaskActivity.class);
context.startActivity(intent);
}
public void createNewTask(View view) {
TextView textView = findViewById(R.id.text_view_id);
myAsyncTask = new MyAsyncTask(textView);
}
public void startTask(View view) {
myAsyncTask.execute();
}
public void cancelTask(View view) {
myAsyncTask.cancel(true);
}
private static class MyAsyncTask extends AsyncTask{
private TextView textView;
public MyAsyncTask(TextView textView){
this.textView = textView;
}
@Override
protected Object doInBackground(Object[] objects) {
for(int counter = 0; counter <= 10; counter ++){
if(!isCancelled()) {
textView.setText(String.valueOf(counter));
SystemClock.sleep(500);
}
else
break;
}
textView.setText("DONE!");
return null;
}
}
答案 0 :(得分:4)
您无法从后台线程更新UI意味着doInBackGround
内的代码在后台线程上运行
@Override
protected Object doInBackground(Object[] objects) {
for(int counter = 0; counter <= 10; counter ++){
if(!isCancelled()) {
textView.setText(String.valueOf(counter));
SystemClock.sleep(500);
}
else
break;
}
textView.setText("DONE!");
// ^^^^^ crash , cannot update UI from background thread
return null;
}
所以改为使用onPostExecuted
protected void onPostExecute(Long result) {
textView.setText("DONE!");
}
注意:如果您取消任务,那么您将发现与textView.setText(String.valueOf(counter));
相同的崩溃。
始终使用generic
类型并传递结果计数器值并相应地更新UI。
private static class MyAsyncTask extends AsyncTask<Void,Void,Integer>{
private TextView textView;
public MyAsyncTask(TextView textView){
this.textView = textView;
}
protected Long doInBackground(Void... obj) {
for(int counter = 0; counter <= 10; counter ++){
if(!isCancelled()) {
SystemClock.sleep(500);
return counter;
}
else
break;
}
return null;
}
protected void onPostExecute(Integer result) {
if(result != null)
textView.setText(String.valueOf(result));
else
textView.setText(String.valueOf("Done"));
// your current code will set done no matter the task is cancelled or not
}
}
答案 1 :(得分:3)
您无法编辑AsyncTask doInBackground中的View(仅限主线程)。所以将setText移动到onPostExecute
@Override
protected void onPostExecute(Void result)
textView.setText("DONE!");
}