0

asyncthread をキャンセルする必要があります。私のアプリケーションでは、いくつかの重い計算を行っています。ユーザーが計算をキャンセルできるようにしたいと考えています (その後、再試行します)。フォーラムで、タスクの実行を停止することはできず、DoinBackground コード内でタスクが isCancelled=true かどうかを確認する必要があることを読みました。しかし、それは私にはうまくいきません。

タスク自体はうまく機能しており、そのままにしておくと正しいデータが出力されます。

私のアプリでは、最初に関数 naredi_pdf_start(view) を呼び出します。タスクの実行中に close_pdf1(view) を呼び出すと、エラーが発生します。 - null ポインター例外)。task.cancel(true) メソッドの使用方法が本当にわかりません(私の場合: start_pdf.cancel(true)))。

これが私のコードです:

String progress_pdf;
naredi_pdf start_pdf;

public void naredi_pdf_start(View view) {
    start_pdf=new naredi_pdf();
    start_pdf.execute();
}

public void close_pdf1(View view) {

    if(start_pdf!=null) {
        Log.v("not null","not null");

        start_pdf.cancel(true);
        setContentView(R.layout.other_view); //This is where 
                                             //I don't have TextView pdf_text1
    }
}

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

    protected Void doInBackground( Void... ignoredParams ) {
        progress_pdf="Calculating Statistical Data";

        //A LOT OF CODING

        for(int i = 0; i < 1; i++) {
            if(isCancelled()) {
                break;
            }
            else {
                publishProgress("Calculating team statistics");  
            }
        }

        //MORE OF CODING              

        for (int i = 0; i < 1; i++) {
            if (isCancelled()) {
                break;
            }
            else {
                publishProgress("Calculating player's BIO");  
            }
        }

        //MORE OF CODING       

        for (int i = 0; i < 1; i++) {
            if (isCancelled()) {
                break;
            }
        else {
                publishProgress("Calculating player's individual performance");
            }
        }

        return null; 
    }

    protected void onPostExecute( Void array ) {
        //saving to database
    }

    protected void onProgressUpdate(String... values) {
        progress_pdf=values[0]+"\n"+progress_pdf;

        if (isCancelled())  {

        }
        else {
            TextView pdf_text1 = (TextView) findViewById (R.id.pdf_text1);
            pdf_text1.setText(progress_pdf);
            // dialog(view);
        }
    }
}
4

3 に答える 3

2

あなたの問題はあなたがキャンセルできないということではありませんAsyncTask。あなたはおそらくNullPointerException、あなたの呼び出しが成功setContentView()する前に通過したために得ます。AsyncTask.cancel()AonProgressUpdate()が呼び出されますが、レイアウトが変更され、!がないことがわかりViewますid=R.id.pdf_text1

AsyncTaskのドキュメントから。

cancel(boolean)を呼び出すことにより、タスクをいつでもキャンセルできます。このメソッドを呼び出すと、isCancelled()への後続の呼び出しはtrueを返します。このメソッドを呼び出した後、doInBackground(Object [])が戻った後、onPostExecute(Object)の代わりにonCancelled(Object)が呼び出されます。タスクができるだけ早くキャンセルされるようにするには、可能であれば、doInBackground(Object [])からisCancelled()の戻り値を定期的にチェックする必要があります(たとえば、ループ内)。

onCancelled()UIスレッドで実行され、その後の呼び出しが発生しないことが確実であるため、をonProgressUpdate()呼び出すのに最適な場所setContentView()です。

onCancelled()あなたの中でオーバーライドAsyncTask

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

    protected Void doInBackground( Void... ignoredParams ) { // YOUR CODE HERE}
    protected void onPostExecute( Void array ) { // YOUR CODE HERE}
    protected void onProgressUpdate(String... values) {// YOUR CODE HERE}

    // ADD THIS
    @Override
    protected void onCancelled() {
        // Do not call super.onCancelled()!

        // Set the new layout
        setContentView(R.id.other_layout);
    }
}

変化するclose_pdf1()

public void close_pdf1(View view) {
    if(start_pdf!=null) {
        Log.v("not null","not null");

        start_pdf.cancel(true);
    }
}

AsyncTaskまた、キャンセルすると自動的にレイアウトが変更される必要があります。うまくいけば、NullPointerExceptionどちらにも遭遇しないはずです。しかし、コードを試していません:)

編集

気になる場合は、の使用に関するRezoomsのアドバイスに従ってくださいreturn

for(int i = 0; i < 1; i++) {
    if(isCancelled()) {
        return null;
    }
    .
    .
    .
}
于 2013-01-11T15:13:28.600 に答える
2

このreturnステートメントは、 ではなく、doInBackground メソッドの実行をキャンセルしbreakます。

于 2013-01-11T14:10:28.617 に答える
0

isCancelledは、AsyncTaskクラスの独自のメソッドです。

拡張クラスでプライベートブールプロパティを定義する必要があります。次のようにします

private class myAsyncTask extends AsyncTask<Void, String, Void> {
          private boolean isTaskCancelled = false;

          public void cancelTask(){
               isTaskCancelled = true;
          }

          private boolean isTaskCancelled(){
               return isTaskCancelled;
          }

          protected Void doInBackground( Void... ignoredParams ) {
            //Do some stuff
             if (isTaskCancelled()){
                return;
             }
          }


          protected void onPostExecute( Void array )
          {
           //Do something
          }



          protected void onProgressUpdate(String... values)
          {
           //Do something
          }
    }
于 2013-01-11T14:19:50.283 に答える