2013-10-22 61 views
7

我試圖從另一個的AsyncTask的doInBackground() - 方法啓動的AsyncTask ...開始的AsyncTask其他的AsyncTask doInBackground()

這甚至可能嗎?如果是的話,我怎麼能做到這一點?

以後編輯:

的想法是,我啓動的AsyncTask,將讓我從高音狀態......一切OK,直到這裏......但是,當我遇到一些具體的鳴叫,我需要一些修改它們從我的服務器的信息,在這裏我會再拍網絡運行,因爲我需要等待,直到我從服務器獲取信息,我做的事:

GetContent getContentServiceAsyncTask = new GetContent(context); 
try { 
    tweetText = Uri.decode(getContentServiceAsyncTask.execute(
      URL_GET_CONTENT, jsonRequest).get()); 
} catch (InterruptedException e) { 
    Log.e(TAG_DEBUG, "InterruptedException: ", e); 
} catch (ExecutionException e) { 
    Log.e(TAG_DEBUG, "ExecutionException: ", e); 
} 

這是從媒體鏈接開始的AsyncTask開始在doInBackground()方法...

我知道我可以ju st在AsyncTask中添加方法,只需在doInBackground()方法中調用它們,但我需要在其他地方使用它們,我從onPostExecute啓動這些AsyncTasks ...

如果你們認爲有一個簡單解決這個問題,這不會影響我的表現,如果不是,我會製作一些靜態方法,我會在我需要的所有AsyncTasks中調用(但這需要我修改很多我的代碼)

+0

你爲什麼要這麼做? http://developer.android.com/reference/android/os/AsyncTask.html。檢查主題線程規則 – Raghunandan

+0

這是可能的,但如果您嘗試從第二個任務上的onPostExecute修改UI,它將會崩潰,因爲它沒有在主線程中執行。 – Juangcg

+0

如果您的第二項任務不包含UI操作,則可以開始。 – nurisezgin

回答

10

按照以下後,你可以做Activity.runOnUiThread()運行在主一個Runnable線程(從另一個線程)。

所以理論上你可以這樣做:

  • 運行的異步任務
  • 活動。runOnUiThread(的Runnable)您的AsyncTask內,從這個運行的

正如它的名字裏面開始一個新的AsyncTask說Activity.runOnUiThread()執行主線程

但它是一種在可運行的哈克。

代碼看起來應該是這樣的:(沒有測試)

// first task 
    (new AsyncTask<String, String, String>() { 

     @Override 
     protected String doInBackground(String... params) { 
      ParentActitity.this.runOnUiThread(new Runnable() { 

       @Override 
       public void run() { 
        //second async stared within a asynctask but on the main thread 
        (new AsyncTask<String, String, String>() { 

         @Override 
         protected String doInBackground(String... params) { 
          // TODO Auto-generated method stub 
          return null; 
         } 

        }).execute(); 

       } 
      }); 
      return null; 
     } 

    }).execute(); 

此嵌套的例子是不是一個好作風在生產中使用,因爲(恕我直言)它接近不可讀。

其他注意事項:

Activity.runOnUiThread(Runnable接口)是靜態!這就是爲什麼我的例子使用ParentActivity(.this).runOnUiThread(Runnable)。

+0

我該如何運行?請記住,我在這樣一個AsyncTask類中: 'public class DoSomeBackgroundWork extends AsyncTask {...}' –

+0

做了一個基本示例 –

+0

謝謝jmeier,但我得到以下警告: 「範圍內沒有可以訪問TwitterActivity類型的封閉實例」 –

14

AsyncTasks應該從主要(UI)線程運行。您不應該從doInBackground運行另一個AsyncTask,因爲此方法在非UI線程上執行。

在你的情況,我可以建議你兩件事情:

  1. 組合在單個請求你都AsyncTaks的處理
  2. 啓動你的第二個的AsyncTask onPostExecute你的第一個任務。
+2

@downvoter:介意解釋downvote的原因? – waqaslam

+3

爲什麼downvote?這是有道理的。 –

+0

我不能這樣做......我需要一個阻塞的AsyncTask,我用.get()調用...我不能等到當前的AsyncTask完成並在onPostExecute()中執行更新。 –

6

你不能在doInBackground()中做,但你可以從onProgressUpdate()例如因爲它在UI線程上運行。只要記住,3.0後,他們會在同一個隊列放,不會並行運行,見executeOnExecutor

+0

我知道有關executeOnExecutor,但我需要我的應用程序在所有版本的Android(> 8)上保持一致。 –

0

請參閱AsyncTask()AsyncTask#execute()的文檔。兩者都聲明它們必須在主UI線程上被調用。

+0

我知道,這就是爲什麼我問你是否知道一些解決方法! –

+1

@lonutNegru你的問題是「這甚至可能」。我的回答是「不」(至少不是直接)。你必須在主線程上發佈一個runnable,其中包含執行新的'AsyncTask'的代碼。 jmeier的回答給出了一種可能的方法來做到這一點。 –

+0

是的,謝謝亞歷克斯洛克伍德,最後我選擇修改結構以避免這個問題,並在未來安全:) ... –

0

基本上我寫的樣本;

public class MainActivity extends Activity { 

View view; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    view = new View(this); 
    setContentView(view); 

    view.setBackgroundColor(Color.RED); 

    new FirstTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null); 
} 

private class FirstTask extends AsyncTask<Void, Void, Void> 
{ 
    @Override 
    protected Void doInBackground(Void... params) { 

     new SecondTask().execute(); 
     try { 
      Thread.currentThread().sleep(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     Log.e("task","first"); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     view.setBackgroundColor(Color.GREEN); 
    } 

} 

private class SecondTask extends AsyncTask<Void, Void, Void> 
{ 
    @Override 
    protected Void doInBackground(Void... params) { 
     Log.e("task","second"); 
     return null; 
    } 
} 

} 
+0

正如Penna所說,Executor是在API級別11中添加的...所以這個是不是我做這件事的方式。 –

-1

它沒有更好地採取這些夫婦INET的行動,並通過啓動一個單獨的線程將處理數據管理的這部分涉及到他們嗎? 谷歌無處不放它的模式,如果你看起來最接近他們都是從簡單的類派生...這個API使得像一個蜘蛛網絡回調涉及回調...嘗試瞭解java的基礎知識,它不會很難寫一個一段好代碼。服務/內容解析器/接收器/裝載器是有限的...線程幾乎能夠實現任何你想要的東西...

你們大多數人沒有想到使用代碼,甚至沒有嘗試去理解它是如何工作的,並理解什麼是編程的關鍵。我儘量不使用基本不知道的代碼。如果我需要,我會徹底研究它。我用黑魔法Java現在我認爲它是數據流A-> B-> C等。好FLOW是必不可少的

編輯:

是我寫的youre問題的解決方案

有很多方法才達到,美想要什麼,但它不是我來寫代碼響應你

  • 你可以使用IntentService類它有一個內置的隊列---只需對每次傳輸使用單獨的startService()調用。

  • 你可以使用線程 - 我的首選方式

  • 您可以使用服務

  • 可以使用AsyncTaskLoader

  • 但如果u需要不使用異步任務火災多於兩個在ONCE上相互連接它們都在MODERN PHONES RUNS上作爲單線程上的QUEUE(ps。你可以運行它們o ñEXECUOR作爲一種變通方法)

由於JAVA 1.5的任務是從線程 分離 - 中加入

什麼都通過自定義線程意味着

線程(在我們說話的話)是不是一個線程類對象,但它處於運行定義的任務()Thread類的方法,以便從THREAD派生的任何類仍然啓動THREAD(又名TASK)

public synchronized void start() { 
     checkNotStarted(); 

     hasBeenStarted = true; 
     /** 
     * look at this line i'ts rerouting run() code of youre thread class 
     * to native method from there thread is created in pure C code 
     */ 
     nativeCreate(this, stackSize, daemon); 
    } 

像這樣的例子在POSIX:

int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * 
    (*start_routine)(void *), void * arg); 

從這個角度,我們可以談論多任務當OS通過同時

執行它們,因爲JAVA 1.5進行過一定的時間段多任務 ther是執行器接口它提供了一種解耦任務提交與每個任務將如何運行的機制的方式,包括線程使用,調度等細節。通常使用執行器而不是顯式創建ng線程。你有很多執行者其中之一是:ThreadPerTaskExecutor

class ThreadPerTaskExecutor implements Executor { 
     public void execute(Runnable r) { 
      new Thread(r).start(); 
     } 
    } 

該執行程序將爲每個任務一個新的線程。

又回到了的AsyncTask:

AsyncTaskM<P, P, R>.executeOnExecutor(Executor,P); 

允許多個任務並行通過的AsyncTask管理線程池運行,但你也可以用你自己的執行人custombehavior。

,是的,如果你不覺得到它,不知道夠不夠beeter給別人做吧:)

我希望這除了改變主意投票。

+0

你的迴應沒有任何辦法達到這個目的,這就是我投票的原因。有更好的方法可以做到這一點,界面,自定義線程,廣播,但當時我發佈的問題,我沒有意識到其中許多人。我還推薦使用EventBus來解耦組件。 –

相關問題