2013-04-25 8 views
16

나는 응용 프로그램을 가지고 있으며 주 스레드에서 네트워크 작업을 수행 할 수 없기 때문에 을 사용하고 있으므로 한 번 질문이 있습니다. execute()AsyncTask 그리고 바로 그 후 finish() 님의 작업이 이루어졌고 아마도 사용자는 finish()입니다. 전체 응용 프로그램, 그래서 제가 궁금하네요 것은 :AsyncTask는 앱이 삭제 된 경우에도 항상 실행됩니까?

  1. AsyncTask 항상 doInBackground()onPostExecute()를 완료됩니다 응용 프로그램은 한 응용 프로그램이 실행되었을 때 execute()가 호출로 종료 된 경우에도?
+4

당신은'AsyncTask를의 cancel' 방법을 사용하여 작업을 실행 취소 활동의 라이프 사이클을 사용해야합니다. UI가 파괴 되더라도 계속 실행될 가능성이있는 네트워크 작업을 계속하는 것은 쓸모가 없습니다. 그러나 네트워크 운영이 완료되면 UI 앱을 업데이트하려고 할 때 문제가 발생합니다. – minhaz

답변

13

테스트 할 수 있습니다. 그리고 그렇습니다. execute가 호출되면 forynctask가 forground 또는 UI와 관련된 작업을 수행하지 않는 한 Asynctask가 여전히 실행되는 것을 볼 수 있습니다. (런처가 충돌 할 수 있습니다).


그러나 시스템에 가까운 경우. 메소드 실행을 계속할 수도,하지 않을 수도 있습니다. 나는 이미 시험하고 대답했다 here.

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     new Worker().execute(); 
    } 
private class Worker extends AsyncTask<Void, Void, String> { 

    @Override 
    protected String doInBackground(Void... arg0) { 
     Log.i("SomeTag", 
       "start do in background at " + System.currentTimeMillis()); 
     String data = null; 

     try { 
      DefaultHttpClient httpClient = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(
        "https://stackoverflow.com/questions/tagged/android"); 

      HttpResponse httpResponse = httpClient.execute(httpGet); 
      HttpEntity httpEntity = httpResponse.getEntity(); 
      data = EntityUtils.toString(httpEntity); 
      Log.i("SomeTag", 
        "doInBackGround done at " + System.currentTimeMillis()); 
     } catch (Exception e) { 
     } 
     return data; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     Log.i("SomeTag", System.currentTimeMillis()/1000L 
       + " post execute \n" + result); 
    } 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    Log.i("SomeTag", System.currentTimeMillis()/1000L + " onDestory()"); 
} 

04-24 21:42:57.981: I/SomeTag(5961): start do in background at 1366854177994 
04-24 21:43:00.974: I/SomeTag(5961): 1366854180 onDestory() 
04-24 21:43:02.946: I/SomeTag(5961): doInBackGround done at 1366854182946 
04-24 21:43:02.946: I/SomeTag(5961): 1366854182 post execute 
04-24 21:43:02.946: I/SomeTag(5961): <!DOCTYPE html> 
04-24 21:43:02.946: I/SomeTag(5961): <html> 
04-24 21:43:02.946: I/SomeTag(5961): <head> 
04-24 21:43:02.946: I/SomeTag(5961):   
04-24 21:43:02.946: I/SomeTag(5961):  <title>Newest &#39;android&#39; Questions - Stack Overflow</title> 
04-24 21:43:02.946: I/SomeTag(5961):  <link rel="shortcut icon" href="http://cdn.sstatic.net/stackoverflow/img/favicon.ico"> 
//.... 
+0

감사합니다 thats 정확히 내가 뭘 궁금 해서요, 내가 가서 약간의 변화를 만들어, 당신이 처음 알았을 때, 바로 당신의 시간을 주셔서 감사합니다 – JRowan

+0

나는 조금 여기에 동의해야합니다. AsyncTasks **는 ** UI 관련 것으로 추정됩니다. 'onPostExecute()'는 ** 항상 ** UI 스레드에서 실행되므로,이 경우 결코 호출되지 않습니다. – ddmps

+0

@Pescis 업데이트 및 테스트되었습니다. 제 테스트가 부정확하다는 것을 알게되면 제 실수를 지적하십시오. – wtsang02

8

onPostExecute()는 UI 스레드에서 호출 - 그래서 UI 스레드가 더 이상 실행중인 경우, 그것은 계속 실행하지 않습니다 : 는 테스트 : 회신 언급합니다. 그러나 doInBackGround()은 별도의 작업자 스레드에서 실행되므로 완료 될 때까지 계속됩니다 (또는 JVM 프로세스가 OS에 의해 종료되는 경우 가능성이 있습니다). AsyncTasks는 UI 바인딩 된 백그라운드 작업이 짧고 장기간 실행되는 백그라운드 작업 (수 초)에만 권장됩니다.

간단히 말해, 계속 진행될 것이라고 가정 할 수 없으며 진행 상황을 게시하거나 onPostExecute()으로 전화를한다고 가정 할 수 없습니다.

4

활동에서 finish()를 호출하면 활동이 삭제되지만 주 스레드는 삭제됩니다. [참고 : 활동은 주 스레드에서 실행됩니다. 활동은 주 스레드가 아닙니다. ]

따라서 백그라운드 스레드의 doInBackground()와 주 스레드의 onPostExecute()가 실행됩니다. 그러나 onPostExecute()가 UI 관련 작업을 수행하면이 시점에서 UI가 없으므로 ANR이 표시됩니다. 예를 들어, onPostExecute() 내에 Log.d() 문만 인쇄하면 문은 Logcat에 표시됩니다.

** 프로세스가 작동 중일 때만 가능하며 &은 Android 저용량 메모리 킬러에 의해 사망하지 않습니다.

1

어떤 스레드에서 어떤 메소드가 실행되는지 보려면 이미지를 참조하십시오.

enter image description here

관련 문제