2010-09-10 87 views
2

我使用AsyncTask爲我的應用程序啓動時爲聯繫人提取鈴聲,它工作正常,直到我的活動在AsyncTask期間關閉了幾次後,在此之後發生AsyncTask將只能進入onPreExecute()並從不doInBackground,所以我永遠不能獲取鈴聲,直到強制停止或設備重新啓動。AsyncTask運行在活動開始失敗先前取消

任何人都可以解釋爲什麼這可能會發生?

爲什麼AsyncTask會進入onPreExecute,但從未運行doInBackground()?

這裏是我的代碼:(繼貨架源代碼)

public void getRingTone(){ 
Log.d("cda", "Into getRingTone"); 
if (audio_service.getStreamVolume(AudioManager.STREAM_RING) > 0) { 
    if(aRingTone != null){ 
     oRingtone = RingtoneManager.getRingtone(this, 
       Uri.parse(aRingTone)); 
    } 
    this.setVolumeControlStream(AudioManager.STREAM_RING); 

} 
} 

private void saveRingToneTask(Bundle outState) { 
final SelectRingtoneTask task = srtt; 
if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) { 
    task.cancel(true); 

    srtt = null; 
} 
} 

private void restoreRingToneTask(Bundle savedInstanceState) { 

     srtt = (SelectRingtoneTask) new SelectRingtoneTask().execute(); 

} 

private void onAddRingTone() { 
srtt = (SelectRingtoneTask) new SelectRingtoneTask().execute(); 

} 

private void onCancelAddRingTone() { 
if (srtt != null && srtt.getStatus() == AsyncTask.Status.RUNNING) { 
    srtt.cancel(true); 
    srtt = null; 
} 
} 

-

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) { 
super.onRestoreInstanceState(savedInstanceState); 
restoreRingToneTask(savedInstanceState); 
} 

@Override 
protected void onSaveInstanceState(Bundle outState) { 
super.onSaveInstanceState(outState); 
if (isFinishing()) { 
    saveRingToneTask(outState); 
} 
} 

private class SelectRingtoneTask extends AsyncTask<String, Void, Void> { 


@Override 
public void onPreExecute() { 
    Log.d("cda", "Into selectRingToneTask - onPreExecute() - " + selectRingtoneFinished); 
    findViewById(R.id.answercallimage).setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      try { 
        serviceBinder.answer(lineId); 
        onCancelAddRingTone(); 
       } catch (RemoteException e) { 

        e.printStackTrace(); 
       } 
     } 
}); 


    findViewById(R.id.declinecallimage).setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 

      mNotificationManager.cancel(2); 
      callConnected = false; 

      try { 
       serviceBinder.reject(lineId); 
       onCancelAddRingTone(); 
      } catch (RemoteException e) { 

       e.printStackTrace(); 
      } 
     } 
}); 

} 



public Void doInBackground(String... params) { 
    Log.d("cda", "Into selectRingToneTask - !!!!!!!!!!!!!!!"); 
    if(!this.isCancelled()){ 
    getRingTone(); 
    } 
    return null; 

} 

@Override 
public void onCancelled() { 
    Log.d("cda", "Into selectRingToneTask - onCancelled() - "); 
} 

@Override 
public void onPostExecute(final Void unused) { 
    selectRingtoneFinished = true; 
     Log.d("cda", "Into selectRingToneTask - onPostExecute - " + selectRingtoneFinished); 
     if(oRingtone != null && playRingTone){ 
      Log.d("cda", "Into getRingTone - PLAY RINGTONE"); 
      oRingtone.play(); 
     } 
} 
} 

而且onAddRingtone()中的onCreate和onCancelRingTone()中的onDestroy(使用)用作以及你可以在上面的代碼中看到。

我已經花了3天時間了,我一直沒能找到解決方案?我採取了錯誤的做法嗎?使用取消錯誤?有錯誤嗎?

+0

是否只有一個任務沒有達到doInBackground,或者這是否適用於首次發現此問題後啓動的所有任務? – softarn 2010-09-10 17:40:44

+0

只有這一個作爲我活動中唯一的一個,將它移動到服務中可能是一個更好的主意? – 2010-09-13 08:30:26

回答

2

我相信發生的事情是你的AsyncTask有一個老活動的句柄,當你在任務中間創建一個新活動時,基本上已經泄露了你的AsyncTask。 DroidFu庫有一個解決方法,通過跟蹤重寫的Application類中的活動活動以及依賴於應用程序的重寫的AsyncTask。幸運的是它的開源,所以你可以看到他們是如何做到的。 Additional Info

+0

我將所有代碼都移到了服務中,但問題依然存在 – 2010-09-13 13:42:20

+0

服務如何通過廣播更新您的用戶界面?它與你原來的問題是分開的問題。 – schwiz 2010-09-13 19:42:01