Question

I'm doing the refactoring of an application that uses AsyncTask to make HTTP calls to a web service.

Now use a simple Activity, at the moment when I needs to invoke the service using a AsyncTask in this way:

  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

 }

I want to do the same but using Android compatibility libraries and FragmentActivity. I read a little about loader but I did not understand how I could use them in this same way, Could you please tell me if this is the right way (FragmentActivity, Fragment and Loader) and how to implement it also addresses giving me examples?

Was it helpful?

Solution

You could create a Loader, something like this:

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;
}
}

In your Fragment, you can initialize this loader:

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;
    ...
}
....
}

And instead of just returning a simple 'String' result, you can return any object you like. Just adjust the MyLoader and LoaderCallbacks implementation accordingly.

OTHER TIPS

You can use Asynctask in Fragment exactly as you did in your Activity, few things change, like:

 progressDialog = new ProgressDialog (home.This);

change to:

progressDialog = new ProgressDialog (getApplication());



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

change to:

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

Anything special to implements Asynctask in Fragment. I think you need to read more about Fragment itself.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top