片段中的AsyncTask

时间:2013-08-26 06:57:12

标签: android android-fragments android-asynctask

我正在使用this文章中描述的方法,在Fragment的AsyncTask中下载和解析html页面。一切都在模拟器上工作正常,但后来我在Galaxy S2上试了一下。当我旋转设备时,listview不会刷新,如果我将设备旋转回来,它会刷新。

以下是我在onCreate中使用my片段的代码(LinksDownloader - 用于解析html的类)

FragmentManager fm = getSupportFragmentManager();
mTaskFragment = (DownloadLinksTaskFragment) fm.findFragmentByTag("task");
if (mTaskFragment == null){
    mTaskFragment = new DownloadLinksTaskFragment();
    mTaskFragment.linksDownloader = new LinksDownloader();
    fm.beginTransaction().add(mTaskFragment, "task").commit();
}
...
goButton.setOnClickListener(new Button.OnClickListener() {
    public void onClick(View v) {
        mTaskFragment.execute();
    }
});
...
linksAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, mTaskFragment.linksDownloader.linksArray);
linksListView.setAdapter(linksAdapter);

片段类

public class DownloadLinksTaskFragment extends Fragment {

static interface TaskCallbacks {
    void onPreExecute();
    void onPostExecute(Byte mssg);
}

private TaskCallbacks mCallbacks;
private DownloadLinksTask mTask;
public LinksDownloader linksDownloader;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    mCallbacks = (TaskCallbacks) activity;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

@Override
public void onDetach() {
    super.onDetach();
    mCallbacks = null;
}

public void execute() {
    mTask = new DownloadLinksTask();
    mTask.execute();
}


private class DownloadLinksTask extends AsyncTask<Void, Void, Byte> {

    @Override
    protected void onPreExecute() {
        if (mCallbacks != null) {
            mCallbacks.onPreExecute();
        }
    }

    @Override
    protected void onPostExecute(Byte b) {
        if (mCallbacks != null) {
            mCallbacks.onPostExecute(b);
        }
    }

    @Override
    protected Byte doInBackground(Void... v) {
        byte exceptionType = 0;
        try {

            linksDownloader.download();

        } catch (HttpStatusException e) {
            exceptionType = 1;
        } catch (WrongContentException e) {
            exceptionType = 2;
        } catch (ConnectTimeoutException e) {
            exceptionType = 3;
        } catch (SocketTimeoutException e) {
            exceptionType = 3;
        } catch (UnknownHostException e) {
            exceptionType = 3;
        } catch (IOException e) {
            exceptionType = 4;
        } catch (Exception e) {
            exceptionType = 5;
        }
        return exceptionType;
    }
}

}

2 个答案:

答案 0 :(得分:2)

如果没有错误,你的实施至少是有争议的。

您要做的是创建片段,其中唯一的角色是下载数据。

您应该将部分UI处理(在您的案例列表视图中)移动到此片段(ListFragment将是合适的)。更好的方法是编写AsyncTaskLoader的实现并将LoaderCallback添加到Fragment中 - 这样可以避免担心屏幕旋转并编写自己的接口和/或处理程序。

答案 1 :(得分:1)

您可以为此创建一个回调接口,并在活动中实现该接口。在片段中创建该接口的引用,并使用片段中getActivity()的{​​{1}}中的接口强制转换onPostExecute()。在活动调用DownloadLinksTask中的该接口的重写方法中刷新列表视图内容。

希望这有帮助