2017-12-21 6 views
2

저는 Android를 처음 사용하고 제 간단한 응용 프로그램에 문제가 있습니다. AsyncTask를 사용하는 매우 간단한 카운터를 사용합니다.내 응용 프로그램이 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; 
     } 
    } 
+2

충돌 로그 게시 – MichaelStoddart

답변

3

당신은 백그라운드 스레드에 doInBackGround 실행 내부의 코드를 의미하는 백그라운드 스레드에서 UI를 업데이트 할 수 없습니다

@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 
    } 
} 
3

당신은 (전용 메인 스레드) AsyncTask를 doInBackground에서보기를 편집 할 수 없습니다. 따라서 setText를 onPostExecute로 이동하십시오.

@Override 
protected void onPostExecute(Void result) 

    textView.setText("DONE!"); 

} 
관련 문제