1

私はプッシュ通知に取り組んでいます。問題は、非常に巨大なフォームを読み込んでいるときに通知を受け取ったときです。フォームが完全に読み込まれる前に、通知をクリックしようとすると、5 ~ 6 秒後に空白の画面が表示されます。例外は、dialog.dismiss によるものです。

私の理解によると、通知を開くと、現在のアクティビティが破棄され、新しいアクティビティが作成されます。新しいアクティビティを作成している間、私は asynctask を使用してアプリの他の機能を実現しています。そのため、現在のアクティビティが破棄されると、アクティビティ コンテキストは null になりますが、asynctask は進行状況ダイアログも引き続き実行されます。アクティビティが破棄されるとすぐに、ダイアログを表示するウィンドウがないため、ウィンドウ リーク例外が発生します。

この問題から抜け出すために誰か助けてもらえますか。また、アプリが長時間アイドル状態のときに空白の画面が表示され、通知を開きます。

アクティビティが破棄されるとすぐに asynctask の実行を停止する方法はありますか?

私のコードは次のとおりです。

public class MainActivity extends Activity {

  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 **  
                 }  
     }  
     }      
}  
 }  

onDestroy() でアクティビティ コンテキストを出力しようとしましたが、null です。

4

3 に答える 3

5

Asynctask の実行を停止できます (それへの参照がある限り)。あなたはこのようなことをしたいかもしれません

開始時:

Task ref = new Task();
ref.execute()

次に onPause() で

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

次に、doInBackground() 内で定期的に何かを行っている場合 (ダウンロードなど)、次のようなものを用意します。

if(isCanceled())
{
    return;
}

上記のスニペットにより、asynctask を正常に終了できるはずです。

onPause でも

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

次に、あなたのonPostExecuteで

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

onPuase で myProgessDialog を null に設定すると、onPOstExecute() で null になります。

于 2013-02-06T19:44:06.083 に答える
2

cancel(Boolean)を呼び出すことで AsyncTask をキャンセルできます。使用方法の詳細については、そのページの「タスクのキャンセル」のctrl-f

于 2013-02-06T19:28:52.723 に答える
1

この問題に対する最善の解決策は、実行中のアプリケーションがまだあるかどうかを非同期タスクにチェックさせることだと思います。そうでない場合は、単に終了します。Activity.onPause にフラグを設定し、出力を送信する前に asynctask にフラグをチェックさせます。

于 2013-02-06T19:33:55.037 に答える