Android 在活动开始时运行的AsyncTask在先前被取消后失败
当我的应用程序启动时,我使用AsyncTask获取联系人的铃声,在AsyncTask期间我的活动关闭几次之后,它才能正常工作,在这种情况发生之后,AsyncTask将只访问onPreExecute(),而不会在后台执行,因此,在强制停止或设备重新启动之前,我无法获取铃声 有人能解释为什么会发生这种情况吗 为什么AsyncTask将进入onPreExecute,但从未运行doInBackground() 这是我的代码:(以下是源代码)Android 在活动开始时运行的AsyncTask在先前被取消后失败,android,android-asynctask,android-1.6-donut,Android,Android Asynctask,Android 1.6 Donut,当我的应用程序启动时,我使用AsyncTask获取联系人的铃声,在AsyncTask期间我的活动关闭几次之后,它才能正常工作,在这种情况发生之后,AsyncTask将只访问onPreExecute(),而不会在后台执行,因此,在强制停止或设备重新启动之前,我无法获取铃声 有人能解释为什么会发生这种情况吗 为什么AsyncTask将进入onPreExecute,但从未运行doInBackground() 这是我的代码:(以下是源代码) -- 私有类SelectRingtoneTask扩
--
私有类SelectRingtoneTask扩展异步任务{
@凌驾
公共无效onPreExecute(){
Log.d(“cda”,“进入selectRingToneTask-onPreExecute()-”+selectRingtoneFinished);
findviewbyd(R.id.answercallimage).setOnClickListener(新的OnClickListener(){
公共void onClick(视图v){
试一试{
serviceBinder.answer(lineId);
OnCanceladringtone();
}捕获(远程异常){
e、 printStackTrace();
}
}
});
findViewById(R.id.declinecallimage).setOnClickListener(新的OnClickListener(){
公共void onClick(视图v){
通知经理。取消(2);
callConnected=false;
试一试{
serviceBinder.reject(lineId);
OnCanceladringtone();
}捕获(远程异常){
e、 printStackTrace();
}
}
});
}
公共Void doInBackground(字符串…参数){
Log.d(“cda”,“进入selectRingToneTask-!!!!!!!!!!!!!”;
如果(!this.isCancelled()){
getRingTone();
}
返回null;
}
@凌驾
已取消的公共无效(){
Log.d(“cda”,“进入selectRingToneTask-onCancelled()-”;
}
@凌驾
公共作废onPostExecute(最终作废未使用){
选择RingToneFinished=true;
Log.d(“cda”,“进入selectRingToneTask-onPostExecute-”+selectRingtoneFinished);
if(原铃声!=null&&playRingTone){
Log.d(“cda”,“进入getRingTone-播放铃声”);
play();
}
}
}
OnAddressTone()用于onCreate,onCancelRingTone()用于onDestroy(),您可以在上面的代码中看到
我已经花了3天时间在这上面,但我还没有找到解决方案?我是不是走错了路?使用取消错误?是否有bug?我相信发生的事情是你的异步任务对旧活动有一个处理,当你在任务中间创建一个新的,你基本上泄漏了你的异步任务。DroidFu库有一个解决方法,它跟踪被重写的应用程序类和依赖于应用程序的被重写的异步任务中的活动。幸运的是它是开源的,所以你可以看到他们是如何做到的 只有一项任务没有到达doInBackground,还是这适用于您第一次注意到此问题后启动的所有任务?只有这项任务是我活动中唯一的任务,将其移动到服务可能是更好的主意?该服务如何通过广播更新您的UI?这与你原来的问题是分开的。
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();
}
}
}