0

我正在重构一个使用 AsyncTask 对 Web 服务进行 HTTP 调用的应用程序。

现在使用一个简单的 Activity,此时我需要以这种方式使用 AsyncTask 调用服务:

  private class MyAsyncTask extends AsyncTask {<String, Void, Boolean>
    private ProgressDialog progressDialog;


    private xmlHandler handler;

    @ Override
    protected void OnPreExecute () {
    progressDialog = new ProgressDialog (home.This);
    progressDialog
    . SetMessage (getString (R.string.home_loadinfo_attendere));
    progressDialog.setCancelable (false);
    progressDialog.show ();
    }

    @ Override
    protected Boolean doInBackground (String... params) {
    try {
    xmlHandler handler = new XmlHandler();
    return Service
    . GetInstance ()
    . CallService (
    ServiceType.GETINFO,
    Home.This, handler, null);
    } Catch (Exception e) {
    e.printStackTrace ();
    return false;
    }
    }

    @ Override
    protected void OnPostExecute (Boolean success) {
    progressDialog.dismiss ();

    String message = null;
    if (success | | (handler == null))
    message = getString (R.string.server_result_msg500);
    else {
    switch (handler.getStatusCode ()) {
    case 200:
    doStuffWithHandler(handler);
    return;
    case 500:
    message = getString (R.string.server_result_msg500);
    break;
    case 520:
    message = getString (R.string.server_result_msg520);
    break;
    default:
    message = getString (R.string.server_result_msg500);
    break;

    }
    }

    if (message! = null) {

    AlertDialog.Builder builder = new AlertDialog.Builder (home.This);
    builder.setTitle (R.string.home_loadinfo_error_title)
    . SetMessage (message)
    . SetCancelable (true)
    . SetNegativeButton (R.string.close_title,
    new DialogInterface.OnClickListener () {
    @ Override
    public void onClick (DialogInterface dialog,
    int id) {
    dialog.cancel ();

    }
    });
    AlertDialog alert = builder.create ();
    Alert.show ();
    }
    }
    }

 doStuffWithHandler(handler){

// populate interface with data from service

 }

我想做同样的事情,但使用 Android 兼容性库和 FragmentActivity。我读了一些关于 loader 的内容,但我不明白如何以同样的方式使用它们,你能否告诉我这是否是正确的方式(FragmentActivity、Fragment 和 Loader)以及如何实现它也解决了给我的例子?

4

2 回答 2

0

您可以像在 Activity 中一样在 Fragment 中使用 Asynctask,几乎没有什么变化,例如:

 progressDialog = new ProgressDialog (home.This);

改成:

progressDialog = new ProgressDialog (getApplication());



 return Service
    . GetInstance ()
    . CallService (
    ServiceType.GETINFO,
    Home.This, handler, null);

改成:

return Service
. GetInstance ()
. CallService (
ServiceType.GETINFO,
getApplication(), handler, null);

在 Fragment 中实现 Asynctask 的任何特殊功能。我认为您需要阅读有关 Fragment 本身的更多信息。

于 2013-02-04T19:07:47.007 回答
0

您可以创建一个加载器,如下所示:

public abstract class MyLoader extends AsyncTaskLoader<String> {
public MyLoader(Context context) {
    super(context);
}

private String result;
protected String error;

@Override
public final String loadInBackground() {
    try {
        error = null;
        // Load your data from the server using HTTP
        ...
        result = ...
        ...
        return result;
    }
    catch (Exception e) {
        Logger.e("ResourceLoader", "Loading resource failed.", e);
        error = e.getMessage();
    }
    return null;
}

@Override
protected void onStartLoading() {
    if (!TextUtils.isEmpty(error)) {
        deliverResult(result);
    }

    if (takeContentChanged()) {
        forceLoad();
    }
}

@Override
public void deliverResult(String data) {
    if (isReset()) {
        return;
    }

    result = data;

    if (isStarted()) {
        try {
            super.deliverResult(data);
        }
        catch(Exception e) { 
            Log.e("ResourceLoader", "Caught exception while delivering result.", e);
        }
    }
}

public String getError() {
    return error;
}
}

在你的片段中,你可以初始化这个加载器:

public class MyLoaderFragment extends Fragment implements LoaderCallbacks<String> {
....
....
String message;

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

    setRetainInstance(true);
        ....
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    getLoaderManager().initLoader(0, getArguments(), this);
}

@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
    return new MyLoader(getActivity());
}

@Override
public void onLoadFinished(Loader<String> loader, String result) {
    // Here you have the result in 'result'.
    message = result;
    ...
}
....
}

您可以返回任何您喜欢的对象,而不是只返回一个简单的“字符串”结果。只需相应地调整 MyLoader 和 LoaderCallbacks 实现。

于 2013-02-04T19:52:51.510 回答