Need an explanation : how to use AsyncTask?

2019-07-16 19:43发布

I have a XML file containing some data, so I created a class representing it :

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

As you can guess I have a list of SpecialData items, each one containing many fields, and currentPage/totalPages are two unique values in the XML file. I need to get and parse the XML file asynchronously, so I created this class :

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

I gave it a try and the problem doesn't come from here because I correctly parse my XML file and my MyData object is perfect. But then I use this task like this in my main Activity class :

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

This may be very silly but I simply don't know how to link my MyData instance from my main class to the one that I get with AsyncTask. What should I do? Thanks.

4条回答
再贱就再见
2楼-- · 2019-07-16 20:21

If you want an AsyncTask to return a data object, you need to store it in a variable in class scope, not function scope. To make this easy, the task is usually a private inner class.

查看更多
我只想做你的唯一
3楼-- · 2019-07-16 20:22

Override AsyncTask's onPostExecute method:

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

Note that this assumes your AsyncTask is an inner class to your activity. If that isn't the case, you can pass in a reference to your Activity in the constructor to your AsyncTask. In those cases, you should be careful to use a WeakReference to your Activity to prevent resource leaks:

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);
 }
查看更多
Emotional °昔
4楼-- · 2019-07-16 20:24

Declare MyData as a variable visible to the whole class and try to access it in onPostExecute() by assigning the result to the MyData variable.

查看更多
Explosion°爆炸
5楼-- · 2019-07-16 20:26

You probably want to implement a callback of some sort. This way you avoid exposing your data by making it publicly accessible, and you can implement other callbacks (such as an error callback if there is a problem loading the data).

For example, you could define an interface like this:

interface MyAsyncFinishedLister {
    void onFinished(MyData resultData);
}

Your AsyncTask will have an instance of MyAsyncFinishedListener, and you can call in onPostExecute as so:

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

Your main activity will implement this interface and look something like:

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;
    }
}
查看更多
登录 后发表回答