2013-03-19 46 views
2

我有一個包含一些數據的XML文件,所以我創建代表它的類:需要說明:如何使用AsyncTask?

public class MyData 
{ 
    ArrayList<SpecialData> list; 
    int currentPage, totalPages; 
} 

正如你能猜到我有SpecialData項目,每一個都包含許多領域的列表,並currentPage/totalPages兩個XML文件中的唯一值。我需要和異步解析XML文件,所以我創建這個類:

class GetXMLTask extends AsyncTask<String, Void, MyData> 
{ 
    @Override 
    protected MyData doInBackground(String... params) 
    { 
     MyData md = null; 
     // Getting/parsing data 
     return md; 
    } 
} 

我給它一個嘗試,問題不從這裏來,因爲我正確地分析我的XML文件和我的MyData對象完善。但後來我用這個任務是這樣,我在主要Activity類:

MyData md = null; 
GetXMLTask task = new GetXMLTask(this); 
task.execute(new String[]{url}); 
// How can this change my md object? 

這可能是非常愚蠢的,但我根本不知道怎麼我的MyData例如從我的主類鏈接到一個我得到AsyncTask。我該怎麼辦?謝謝。

+0

爲什麼你不聲明MyData作爲一個gl obal變量並嘗試在'onPostExecute()'中訪問它? – Swayam 2013-03-19 17:21:38

+0

這聽起來像你可能想要一個'Future '。 – Richard 2013-03-19 17:23:32

+0

你應該可以只執行'task.execute(url)',而不是'new String [] {url}' – ianhanniballake 2013-03-19 18:45:33

回答

6

覆蓋AsyncTaskonPostExecute方法:

protected void onPostExecute(MyData result) { 
    md = result; 
} 

請注意,這是假定您的AsyncTask是一個內部類的活動。如果不是這種情況,可以將構造函數中的Activity的引用傳遞給AsyncTask。在這種情況下,你應該小心使用WeakReference你的活動,以避免資源泄漏:

GetXMLTask(MyActivity activity) 
{ 
    this.mActivity = new WeakReference<MyActivity>(activity); 
} 

protected void onPostExecute(MyData result) 
{ 
    MyActivity activity = this.mActivity.get(); 
    if (activity == null) // Activity was destroyed due to orientation change, etc. 
     return; 
    activity.updateUiFromXml(result); 
} 
+0

所以'md'是我主要活動的領域? – Rob 2013-03-19 17:34:12

+0

@Rob - 是的,'md'就是你希望doInBackground結果去的地方。當然,你可能想調用'MyActivity'中的方法來更新帶有MyData的UI,或者直接在'onPostExecute'中做UI更新。 – ianhanniballake 2013-03-19 17:37:21

+0

@ianhanniballake這是很骯髒的...打破封裝。 – Tushar 2013-03-19 17:38:49

1

如果你想要一個AsyncTask返回一個數據對象,你需要將它存儲在一個類作用域中的變量中,而不是函數作用域。爲了使這個變得簡單,任務通常是一個私人的內部類。

1

聲明MyData作爲變量可見全班並試圖通過分配訪問它在onPostExecute() MyData變量的結果。

2

你可能想要實現某種回調。通過這種方式,您可以通過公開訪問來避免公開數據,並且可以實現其他回調(例如,如果加載數據時出現問題,則返回錯誤回調)。

例如,你可以定義一個接口是這樣的:

interface MyAsyncFinishedLister { 
    void onFinished(MyData resultData); 
} 

你的AsyncTask將有MyAsyncFinishedListener的實例,你可以在onPostExecute調用像這樣:

protected void onPostExecute(MyData result) { 
    myAsyncFinishedListener.onFinished(result); 
} 

您的主要活動將實現這個接口,看起來像這樣:

class MyActivity extends Activity implements MyAsyncFinishedListener { 
    MyData md; 

    public void onCreate() { 
     super.onCreate(); 

     GetXMLTask task = new GetXMLTask(this); 
     task.execute(new String[]{url}); 
     task.setOnFinishedListener(this); 
    } 

    onFinished(MyData result) { 
     md = result; 
    } 
}