2

アプリケーションの起動時に連絡先の着信音を取得するために AsyncTask を使用しています。AsyncTask 中にアクティビティが数回閉じられるまで正常に動作します。これが発生した後、AsyncTask は onPreExecute() にのみ到達し、doInBackground には到達しません。 、そのため、強制停止またはデバイスの再起動のいずれかが行われるまで、着信音を取得することはできません。

なぜこれが起こっているのか、誰か説明できますか?

AsyncTask が onPreExecute に到達するのに doInBackground() を実行しないのはなぜですか?

ここに私のコードがあります:(Shelfのソースコードに従う)

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 日間費やしましたが、解決策を見つけることができませんでしたか? 私は間違ったアプローチを取っていますか?キャンセルの使い方が間違っていませんか?バグはありますか?

4

1 に答える 1

2

何が起こっているかは、AsyncTask が古いアクティビティを処理していることだと思います。タスクの途中で新しいアクティビティを作成すると、本質的に AsyncTask がリークされます。DroidFu ライブラリには、オーバーライドされた Application クラスと、アプリケーションに依存するオーバーライドされた AsyncTask でアクティブなアクティビティを追跡することで、この問題を回避する方法があります。幸いなことに、オープンソースなので、彼らがどのようにそれを行うかを見ることができます. 追加情報

于 2010-09-10T16:53:57.923 に答える