2012-06-15 70 views
2

這裏是我的代碼:的AsyncTask無法調用doInBackground方法

new Loading.LoadTast(ctx) { 

      @Override 
      protected String doInBackground(Integer... params) { 
       Looper.prepare(); 
       String msg=changePwd(); 
       closeProgressDialog(); 
       if(msg == null) { 
        SmartNgApplication.getInstance().exit(); 
       } else { 
        BaseHelper.showToast(ctx, msg); 
       } 
       Looper.loop(); 
       return null; 
      } 
     }.execute(); 


public abstract static class LoadTast extends AsyncTask<Integer, Integer, String> { 

    private ProgressDialog progressDialog; 

    private Context ctx; 

    public LoadTast(Context ctx) { 
     this.ctx=ctx; 
    } 

    protected abstract String doInBackground(Integer... params); 

    public void onPreExecute() { 
     super.onPreExecute(); 
     progressDialog=ProgressDialog.show(ctx, "", "loading...", true, false); 
    } 

    public void onPostExecute(String result) { 
     super.onPostExecute(result); 
     progressDialog.dismiss(); 
     BaseHelper.showToast(ctx, result); 
    } 
} 

點擊按鈕運行的方法。點擊它5次AsyncTask.onPreExecute被稱爲但不叫doInBackground所以屏幕仍然顯示一個對話框。

我覺得有AsyncTaskTHREAD_POOL_EXECUTOR

+0

爲什麼覆蓋'doInBackground()'方法如此重要?爲什麼不把它放在'AsyncTask'內? –

+0

因爲在許多Class中調用了新的Loading.LoadTast(ctx),而且我不想在每個類上寫PreExecute方法 – Sunxc

+0

您不必?一旦你創建了你的課程,那麼你所需要做的就是調用'新的LoadTast。execute([int params]);'另外,你需要聲明你的'AsyncTask'將使用哪些變量,例如'public abstract static class LoadTast extends AsyncTask <'','Integer,Void> {' –

回答

2
  1. 你不應該調用任何UI改變doInBackground方法有些不妥。那就是onPostExecute在那裏。只做doInBackground中UI線程不允許的內容。

  2. 要檢查爲什麼doInBackground未被調用,請嘗試將實現(從匿名內部類)放入LoadTast中,以查看它是否被調用。

  3. 我已經通過將子類調用onPostExecute和doInBackground重命名實現了一個AsyncWrapper。應該可以在你的例子中使用的匿名內部類中覆蓋包裝好的方法。

這是短版本。我的真實代碼涉及一些常規異常處理,不僅包含對包裝方法的調用。

public abstract class AsyncTaskWrapper<Params, Progress, Result> 
    extends AsyncTask<Params, Progress, Result> { 

    @Override 
    final protected Result doInBackground(Params... params) { 
    return wrappedDoInBackground(params); 
    } 

    protected abstract Result wrappedDoInBackground(Params... params); 

    protected abstract void wrappedOnPostExecute(Result result); 

    final protected void onPostExecute(Result result) { 

    wrappedOnPostExecute(result); 
    } 

} 
+0

阿門。有關AsyncTask的更多信息,請參閱此博文http://blogactivity.wordpress.com/2011/09/01/proper-use-of-asynctask/ – slezica

1

託德Sjolander在this thread說...

的多線程模型2.3.5和4.0.4之間的變化。 AsyncTask 現在默認爲使應用程序中的所有子類都使用相同的 線程(即,一次只能運行一個AsyncTask!)。這裏解釋了 這裏:

當第一次引入時,AsyncTasks在一個後臺線程上連續執行。從DONUT開始,將其更改爲允許多個任務並行操作的 線程池。從 HONEYCOMB開始,任務在單個線程上執行,以避免並行執行導致的常見應用程序錯誤 。

如果你真的想並行執行,你可以調用 executeOnExecutor與 THREAD_POOL_EXECUTOR(java.util.concurrent.Executor,對象[])。

考慮到這一點,它可能是另一個AsyncTask在 您的應用程序中運行,從而阻止這個啓動。那 解釋了爲什麼它可以在你的2.3.5設備上正常工作,但不是你的4.0.4 平板電腦。

相關問題