2013-10-22 115 views
3

我試圖從我的AsInctask的DoInBackground中返回值,但是調用get()方法會凍結我的UI。我怎樣才能將我的代碼重新寫入回調方法? :沒有get()方法的AsyncTask返回值

public class GetUrlDataTask extends AsyncTask<String, Integer, String> { 
String response; 
HttpUtils util; 
@Override 
protected String doInBackground(String... params) { 
    try { 
     util = new HttpUtils(params[0]); 
     response = util.getContent(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return response; 
} 

@Override 
protected void onPostExecute(String result) { 
    super.onPostExecute(result); 
} 

在我的活動我得到的結果response = new GetUrlDataTask().execute("site").get;

+0

這與async完全相反。你需要使用回調。 – SLaks

+0

您可以使用廣播接收器或可能事件總線意圖,回調是一個好主意太 –

+1

您可以使它成爲一個內部類,並直接從'onPostExecute(調用'Activity'方法)'或[見這個答案](HTTP:/ /stackoverflow.com/questions/18517400/inner-class-can-access-but-not-update-values-asynctask/18517648#18517648)關於使用'interface'用'AsyncTask' – codeMagic

回答

10

[更新]現在,我建議使用的標註。使用註釋可以注入視圖,只需幾個字母就可以在編譯步驟中使用asyncronous過程的功能。檢查github上的butterknife庫。

ButterKnife

您可以創建界面,將它傳遞給的AsyncTask(在構造函數),然後調用方法onPostExecute

例如:

你的接口:

public interface OnTaskCompleted{ 
    void onTaskCompleted(); 
} 

您的活動:

public YourActivity implements OnTaskCompleted{ 
    //your Activity 
} 

和你的AsyncTask:

public YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type 
    private OnTaskCompleted listener; 

    public YourTask(OnTaskCompleted listener){ 
     this.listener=listener; 
    } 

    //required methods 

    protected void onPostExecute(Object o){ 
     //your stuff 
     listener.onTaskCompleted(); 
    } 
} 
+0

有在回調空的expirience。 YourTask如何知道我的活動包含的變量? – Sunstrike

+0

在onPostExecute @Flextra蔭越來越對象如何設置對象自動圖文集,執行另一個AsynchronusTask請幫我 – Harsha

6

,則不應使用。獲得()如果異步任務是要採取任何時間體面的數量(通常是這樣)。相反,你可以使用消息/處理程序/服務/ etc,或者你可以簡單地使用onPostExecute(Result)方法。

編輯:新代碼。根據你的描述,你似乎需要使用一個界面。

如果你需要在另一個類中有Asynctask,那麼接口可能是你最好的選擇。

TestTask.java(你單獨的AsyncTask):

import android.os.AsyncTask; 

// Remember to change object type <> to what you need 
public class TestTask extends AsyncTask<Object,Object,Object> { 

    public interface OnTaskCompleted{ 
     void onTaskCompleted(); 
    } 

    private OnTaskCompleted listener; 

    public TestTask(OnTaskCompleted listener){ 
     this.listener = listener; 
    } 

    protected void onPostExecute(Object o){ 
     // Call the interface method 
     if (listener != null) 
      listener.onTaskCompleted(); 
    } 

    @Override 
    protected Object doInBackground(Object... params) { 
     // The sleep() is just to simulate activity and delay 
     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 

MainActivity.java(或任何其他活動):

public class MainActivity extends Activity { 

private boolean status = false; 

private OnTaskCompleted listener = new OnTaskCompleted() { 
    public void onTaskCompleted() { 
     status = true; 
     Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show(); 
    } 
}; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show(); 
    new TestTask(listener).execute("Testing"); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

} 
+0

我有同樣的問題的AsyncTask另一個類,但其非常大的,而且我可以包括它在我的活動課。 – Sunstrike

+0

更新了原件以反映您的需求。上面的代碼已經過測試和工作。你可以改變界面來做你需要的。接口的想法是或多或少地具有由所謂的AsyncTask和活動的內執行的方法,因此回調概念。 –

+0

但我還是不明白如何返回值。我需要在onTaskCompleted();中寫入「返回字符串」的內容。 – Sunstrike

0

你可以做這樣的事情:

public class MyActivity extends Activity 
{ 
    public void someMethod() 
    { 
    // Here you could put up a ProgressDialog 

    GetUrlDataTask myTask = new GetUrlDataTask(); 
    myTask.execute(); 
    } 

    public class GetUrlDataTask extends AsyncTask<String, Integer, String> 
    { 
    @Override 
    protected String doInBackground(String... params) 
    { 
     String response = null; 
     HttpUtils util; 

     try 
     { 
     util = new HttpUtils(params[0]); 
     response = util.getContent(); 
     } 
     catch (Exception e) 
     { 
     e.printStackTrace(); 
     response = e.getMessage(); 
     } 
     return response; 
    } 

    @Override 
    protected void onPostExecute(String result) 
    { 
     // Here you can dismiss the ProgressDialog and display the result 
    } 
    } 
} 
1

我是n非常喜歡在單獨的課程中使用AsycTask任務,特別是如果您需要使用響應。考慮到作爲內部類實現它有多容易,它使響應和局部變量交互過於困難。

我猜你把它放在它自己的類中,所以你可以重用它。我會考慮將AsycTask作爲一個內部類,並在doInBackground()中調用外部可重用對象/方法。這將使代碼保持乾爽,並允許您的活動按照響應所需進行。

public class MyActivity extends Activity { 
    TextView textview; 

    //... 

    private class GetUrlTask extends AsyncTask<String, Integer, String> { 

     protected String doInBackground(String... params) { 
      return new GetHttpResponse().get(params[0]); 
     } 

     protected void onPostExecute(String response) { 
      //Do UI updates... 
      textview.setText(response); 
     } 
    } 
} 


public class GetHttpResponse { 

    public String get(String url) { 
     try { 
      util = new HttpUtils(url); 
      response = util.getContent(); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    return response; 
    } 
} 
+0

而如果我有三個使用此任務的活動? – Sunstrike