2013-02-06 4 views
1

푸시 알림 작업 중입니다. 문제는 내가 매우 거대하고 양식을 완전히로드하기 전에 알림을받는 알림을 클릭하면 5-6 초 후에 빈 화면이 나타납니다 양식을로드 할 때입니다. 예외는 dialog.dismiss 때문입니다.활동이 파괴되었지만 asynctask가 여전히 실행 중입니다.

내 이해에 따르면 알림을 여는 동안 현재 활동이 삭제되고 새로운 활동이 만들어집니다. 새로운 액티비티를 만드는 동안 asynctask를 사용하여 내 앱에서 다른 기능을 수행합니다. 따라서 현재 액티비티가 파기되면 액티비티 컨텍스트는 null이지만 asynctask는 여전히 진행 대화 상자를 실행 중입니다. 액티비티가 파괴 되 자마자 대화 상자를 표시 할 창이 없으므로 창에서 예외가 누출됩니다.

아무도 나를이 문제에서 벗어나도록 도울 수 있습니다. 앱이 오랫동안 유휴 상태 일 때 빈 화면이 나타나면 알림을 엽니 다.

활동이 삭제되는 즉시 asynctask 실행을 중지 할 수있는 방법이 있습니까?

내 코드는 다음과 같습니다

공용 클래스 MainActivity 내가들의 OnDestroy()에서 활동 컨텍스트를 인쇄하려 활동 {

private MyProgressDialog myProgressDialog; 
    public LinearLayout mainPanel; 
    private VMobilet mobilet = null; 
    private String mobiletId; 
    private String formId ; 

    @Override 
protected void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(mainPanel); 

    Intent i = getIntent(); 
    mobiletId = i.getStringExtra("Mobilet Id"); 
    formId = i.getStringExtra("Form ID"); 
      VUiHelper.getInstance().setIsFinish(false); 
    myProgressDialog = MyProgressDialog.show(MainActivity.this,"","",true); 

    BackgroundTask backgroundTask = new BackgroundTask(); 
    backgroundTask.execute(MainActivity.this); 
} 

    @Override 
protected void onPause() { 
    super.onPause(); 
    if(VUiHelper.getInstance().isFinish()) 
     {   
      this.finish();  
     }  
    else { 
     System.out.println("pausing mainactivity"); 
    } 
} 

    @Override 
protected void onDestroy() { 
    super.onDestroy(); 
    System.out.println("mainactivity ondestroy called"); 
    if(mobilet != null) 
    mobilet.getForms().clear(); 
    mobilet = null; 
    mainPanel = null; 
    VUiHelper.getInstance().clearControlCache(); 
    VUiHelper.getInstance().MediaInput.clear(); 
    System.gc(); 
} 

    private class BackgroundTask extends AsyncTask<Context, String, Boolean> { 

    @Override 
    public void onPreExecute() {  
     super.onPreExecute(); 
    } 

    @Override 
    protected Boolean doInBackground(Context... arg0) { 
     if (mobiletId != null) { 
      ** some logic ** 
     } 
     return true; 
    } 

    @Override 
    public void onPostExecute(Boolean status){    
     super.onPostExecute(status);   
     myProgressDialog.dismiss(); //dismissing the progress dialogs  
     if (mobilet != null) { 
         ** some logic ** 
     } else { 
       ** some logic ** 
       } 
    } 
    }  
} 
} 

를 확장하고는 null입니다.

+0

또한 난을 복원하려면 asynctask의 인스턴스를 작성하고 작성 될 새 활동으로 전달하십시오. – user1525410

답변

2

cancel(Boolean)을 호출하여 AsyncTask를 취소 할 수 있습니다. 더 많은 사용 정보를 보려면 해당 페이지의 "작업 취소"에 대한

+1

"이 작업의 실행을 취소하려고 시도합니다." Asynctasks는 우선 순위가 낮은 스레드입니다. 그리고 스레드는 자바에서 안정적으로 죽일 수 없습니다. – tmanthey

+0

참.이것이 가능한 한 빨리 종료해야하는 경우 백그라운드 메서드에서 isCancelled()를 주기적으로 검사하는 것이 좋습니다. – jqpubliq

+0

AsyncTask에서 cancel (** true **)을 호출하면 백그라운드에서 대부분의 I/O 호출을 차단합니다 AsyncTask의 스레드가 인터럽트됩니다. –

1

문제에 대한 최선의 해결책은 여전히 ​​실행중인 응용 프로그램인지 여부를 asyntask가 확인하도록하는 것입니다. 단순히 종료하지 않으면. Activity.onPause에 플래그를 설정하고 asynctask가 출력을 보내기 전에 체크합니다.

5

Asynctask 실행을 중지 할 수 있습니다 (참조가있는 한). 시작할 때이

같은 작업을 수행 할 수 있습니다 :

Task ref = new Task(); 
ref.execute() 
onPause에서 다음

() 당신의 doInBackground() 안에 다음

if(ref != null) 
    ref.cancel(true); 

를 주기적으로 일을하는 경우 (다운로드 등) 다음과 같이 설정하십시오 :

if(isCanceled()) 
{ 
    return; 
} 

위의 스 니펫을 사용하면 grac asynctask를 종료합니다. 당신의 onPause onPuase에 null로 myProgessDialog의 설정이 onPOstExecute()에서이 null해야

if(myProgressDialog != null) 
{ 
    if(myProgressDialog.isShowing()) 
    { 
     myProgessDialog.dismiss; 
     myProgessDialog = null; 
    } 
} 

당신의 onPostExecute에서 다음

if(myProgressDialog != null) 
{ 
    if(myProgressDialog.isShowing()) 
    { 
     myProgressDialog.dismiss() 
    } 
    myProgressDialog = null 
} 

에서 또한

+0

나는 이것을 시도했지만 여전히 같은 문제가있다. – user1525410

+0

당신은 그것이 백그라운드에서 실행될 때까지 말하고 있습니다. 작업 취소 (true)를 설정하면 doInBackground가 끝나자 마자 onPostExecute()를 호출하면 안됩니다. 또한 onPostExecute 호출 중임을 나타내는 Log 문을 출력합니다. 왜냐하면 그것은 일어나서는 안되기 때문입니다. – Raigex

관련 문제