2013-05-02 132 views
-3

出於某種原因,我致電AsyncTask.cancel的呼叫僅適用於一次,即針對任務的第一個實例,而不再運行。第一項任務取消,並擊中onCancelled方法。所有其他人似乎忽略cancel()呼叫,並以onPostExecute結束。AsyncTask.cancel僅適用於一次

的任務是從服務執行:

public class ZitFtpService extends Service implements ZitFtpServiceInterface 
{ 
//Blah blah 

public void connect(String server, int port) 
{ 
    if(!isConnecting){ 
     isConnecting = true; 
     ConnectTask task = new ConnectTask(); 
     task.execute(server, String.valueOf(port)); 
    } 
    } 
    //Blah blah blah 

正如你可以看到它是每當一個新的實例。我看不出爲什麼第一個人的行爲與後來的行爲有所不同。該AsyncTask是一個私有內部類:

private class ConnectTask extends AsyncTask<String, String, Boolean> { 

    @Override 
    protected Boolean doInBackground(String... params) { 

     boolean result = false; 

     try { 
      publishProgress(
        "start", "Connecting to "+ params[0] + ":" + params[1]); 
      Log.v("ZIT", params[0] + " " + params[1] + " " + params.length); 
      conn.connect(params[0], Integer.valueOf(params[1]), 1000); 
      result = true; 
      } catch (NumberFormatException e) { 
      Log.e("ZIT", e.getMessage()); 
     } catch (IOException e) { 
       failMessage = e.getMessage(); 
       e.printStackTrace(); 
      } 
     return Boolean.valueOf(result); 
    } 

    private void cancelConnect() { 
     try { 
      conn.disconnect(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      conn = new ZMobileFTPImpl(); 
     } 

     if(!(dialog==null)) { 
      dialog.dismiss(); 
     } 
    } 

    @Override 
    protected void onCancelled() { 
     Log.v("ZIT", "I was cancelled."); 
     isConnecting = false; 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 

     if(dialog == null) { 
      dialog = new ProgressDialog(progressActivity); 
      dialog.setCancelable(true); 
      dialog.setOnCancelListener(new OnCancelListener() { 

       @Override 
       public void onCancel(DialogInterface dialog) { 
        ConnectTask.this.cancel(true); 
        cancelConnect(); 
        dialog.dismiss(); 

       } 
      }); 
      dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
        new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 
     } 

     dialog.setMessage(values[1]); 
     dialog.setCancelable(true); 
     dialog.show(); 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 

     dialog.dismiss(); 
     if(!result) { 
      AlertDialog.Builder builder = 
        new AlertDialog.Builder(progressActivity); 
      builder.setMessage(failMessage).setTitle("Error"); 
      failMessage = ""; 
      builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int id) { 
         dialog.dismiss(); 
        } 
       }); 
      AlertDialog failDialog = builder.create(); 
      failDialog.show(); 
     } 

     isConnecting = false; 
    } 
} 
+0

很難說,但最重要的是在你的代碼中的一些錯誤。您在AsyncTask中使用全局變量,您也可以使用這些變量來確定是否運行新任務。請通過您的任務創建過程進行調試 – httpdispatch 2013-05-02 08:17:25

回答

1

From Doc's

有必須遵循此類才能正常工作的幾個線程規則:

  • 的的AsyncTask類必須加載在UI線程上。這從JELLY_BEAN自動完成。
  • 任務實例必須在UI線程上創建。
  • execute(Params...)必須在UI線程上調用。
  • 請勿手動撥打onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)
  • 任務只能執行一次(如果第二試圖執行一個異常將被拋出。)

所以,你可以通過像

new ConnectTask().execute(params); 
每次創建新實例調用的AsyncTask多次
0

這是故意的,你只能執行的AsyncTask實例一次,就可以運行雖然task.execute多次...

無論如何,我相信你忘了加上super.onCancelled在以下重寫:

@Override 
public void onCancelled() { 
    //... 
    super.onCancelled(); 
} 

嘗試,如果是幫助,否則你應該分享錯誤或日誌,所以我們可以解決問題,:)