2013-03-19 53 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; 
    } 
}