2014-04-23 43 views
2

我想在後臺進程中發佈兩種不同的進度。我試圖在某個時間發佈一個字符串,而另一次發佈一個整數。我在onProgressUpdate中通過重載它們來處理兩種參數。但是當我聲明我的AsyncTask類時,我有這樣的理由,那就是爲什麼它期望我只發送字符串類型參數。有沒有辦法處理這兩種類型的publishProgress事件?可以發佈進程在AsyncTask中重載嗎?

+0

沒有辦法使用標準的AsyncTask做到這一點 - 你要麼必須使用一個類型,這兩種類型都符合,或實現自己的AsyncTask。 – Dyrborg

+0

我在我的嵌套AsyncTask類的活動中實現了SensorEventListener類。我不能只是創建一個字符串全局變量,並更新AsyncTask中的變量,並且onSensorChanged()方法會選取變量並將其設置爲文本?我完全可以避免postProgress()方法嗎? –

+0

如果我正確理解你,那將是一個非常糟糕的設計策略。創建自己的AsyncTask實現將會更好,它支持多種更新方法,因此您不僅限於1種方法。或者,您可以在publishUpdate()方法中始終使用字符串,然後在onProgressUpdate()中檢查字符串是否爲整數(使用Integer.parseInt(您的字符串)),並相應地執行操作。 – Dyrborg

回答

3

基本上有解決你的問題,有兩種方式:

第一個是非常簡單的,你只是一直publishUpdate(String),然後在你的onProgressUpdate(String)檢查字符串是否是一個int或字符串,並處理每情況不同,像這樣:

private class MyAsyncTask extends AsyncTask<Void, String, Void> { 
    //Executed on main UI thread. 
    @Override 
    protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 
     try{ 
      Integer i = Integer.parseInt(values[0]); 
      TextView v1 = (TextView) findViewById(R.id.textView1); 
      v1.setText(String.valueOf(i)); 
     } 
     catch(NumberFormatException e){ 
      TextView v2 = (TextView) findViewById(R.id.textView3); 
      v2.setText(values[0]); 
     } 
    } 
    @Override 
    protected Void doInBackground(Void... params) { 
     int i = 0; 
     while(i < 100){ 
      try { 
       if(i%2 == 0){ 
        publishProgress("Divisible by 2: " + String.valueOf(i)); 
       } 
       publishProgress(String.valueOf(i)); 
       i++; 
       Thread.sleep(500); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     return null; 
    } 
} 

在上面的例子中,我只是嘗試解析字符串的Integer - 如果它的工作原理,然後我100%肯定它是一個int - 如果它拋出一個異常,那麼它是一個String

但是,如果您想要更多控制,則需要實現您自己的AsyncTask版本,該版本支持一個或多個進度更新。可以實現這一點的唯一方法是通過使用Handlershttp://developer.android.com/reference/android/os/Handler.html)和Threadhttp://developer.android.com/reference/java/lang/Thread.html)直接(優選包裝在多個邏輯類類似的AsyncTask):

import android.os.Handler; 
import android.os.Looper; 

public abstract class DIYAsyncTask<Params, IntProgress, StringProgress, Result> { 

    private Result backGroundResult; 

    //Run on UI thread 
    @SuppressWarnings("unchecked") 
    protected void execute(Params... params){ 
     final Params[] thisParams = params; 
     Thread worker = new Thread(){ 
      public void run(){ 
       prepareForPreExecute(); 
       backGroundResult = doInBackground(thisParams); 
       prepareForPostExecute(); 
      } 
     }; 
     worker.setPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); 
     worker.start(); 
    } 

    //Code to start onPreExecute on UI thread 
    private void prepareForPreExecute(){ 
     Handler ui_handler = new Handler(Looper.getMainLooper()); 
     ui_handler.post(
       new Runnable(){ 
        public void run(){ 
         onPreExecute(); 
        } 
       } 
      ); 
    } 

    //Code to start onPostExecute on UI thread 
    private void prepareForPostExecute(){ 
     Handler ui_handler = new Handler(Looper.getMainLooper()); 
     ui_handler.post(
       new Runnable(){ 
        public void run(){ 
         onPostExecute(backGroundResult); 
        } 
       } 
      ); 
    } 

    //Always run on worker thread 
    @SuppressWarnings("unchecked") 
    protected abstract Result doInBackground(Params... params); 

    //Always run on UI 
    protected void onPreExecute(){ 
    } 

    //Always run on UI 
    protected void onPostExecute(Result result){ 
    } 

    //Run on worker 
    @SuppressWarnings("unchecked") 
    protected void publishIntProgress(IntProgress... values){ 
     Handler ui_handler = new Handler(Looper.getMainLooper()); 
     final IntProgress[] thisProgress = values; 
     ui_handler.post(
       new Runnable(){ 
        @Override 
        public void run(){ 
         onIntProgressUpdate(thisProgress); 
        } 
       } 
     ); 
    } 

    //Always run on UI 
    @SuppressWarnings("unchecked") 
    protected void onIntProgressUpdate(IntProgress... values){ 

    } 

    //Run on worker 
    @SuppressWarnings("unchecked") 
    protected void publishStringProgress(StringProgress... values){ 
     Handler ui_handler = new Handler(Looper.getMainLooper()); 
     final StringProgress[] thisProgress = values; 
     ui_handler.post(
       new Runnable(){ 
        @Override 
        public void run(){ 
         onStringProgressUpdate(thisProgress); 
        } 
       } 
     ); 
    } 

    //Always run on UI 
    @SuppressWarnings("unchecked") 
    protected void onStringProgressUpdate(StringProgress... values){ 

    } 
} 

然後可以覆蓋這樣(注意只是利用相似的AsyncTask)

private class MyDIYAsyncTask extends DIYAsyncTask<Void, Integer, String, Void> { 

    //Executed on main UI thread. 
    @Override 
    protected void onIntProgressUpdate(Integer... values) { 
     super.onIntProgressUpdate(values); 
     TextView v = (TextView) findViewById(R.id.textView1); 
     v.setText(String.valueOf(values[0])); 
    } 

    @Override 
    protected void onStringProgressUpdate(String... values) { 
     super.onStringProgressUpdate(values); 
     TextView v = (TextView) findViewById(R.id.textView3); 
     v.setText(values[0]); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 

     int i = 0; 
     while(i < 100){ 
      try { 
       publishIntProgress(i); 
       publishStringProgress("MyString" + String.valueOf(i)); 
       i++; 
       Thread.sleep(500); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     return null; 
    } 

} 
相關問題