Skip to content Skip to sidebar Skip to footer

Asynctask For Downloading Data And Saving Into Variable?

I have the downloading part done using Retriever.getCourses(username,password), but the following code gives me an error later on saying Values.Courses is set to null. I think I wr

Solution 1:

inside doInBackground you have returned null, instead return courses. What you return there will be sent as a parameter to onPostExecute

Solution 2:

As mentioned in the comments and referred to my other answer, an AsyncTask, is asynchronous, hence the name. In other words, you are not guaranteed a value for your variables that you assign within onPostExecute and you shouldn't use those variables in your Activities / Fragments until you are sure they have a value.

The way to appropriately handle the asynchronous nature and ensure you have a value is to use a callback function. From that link, I defined a generic interface to pass results around between classes.

publicinterfaceAsyncResponse<T> {
    voidonResponse(T response);
}

You can define your AsyncTasks as such for login

publicclassUserLoginTaskextendsAsyncTask<Void, Void, Boolean> {

    private final String muser;
    private final String mPassword;
    private final AsyncResponse<Boolean> callback;

    publicUserLoginTask(String user, String password, AsyncResponse<Boolean> callback) {
        this.muser = user;
        this.mPassword = password;
        this.callback = callback;
    }

    @OverrideprotectedBooleandoInBackground(Void... voids) {

        boolean login = false;

        // TODO: Some network operationtry {
            login = doLogin(this.muser, this.mPassword);
        } catch (Exception e) {
            Log.e("LoginError", e.getMessage());
        }

        return login;
    }

    @OverrideprotectedvoidonPostExecute(Boolean response) {
        if (callback != null) {
            callback.onResponse(response);
        }
    }
}

And to get the courses

publicclassGetCoursesTaskextendsAsyncTask<Void, Void, List<Course>> {

    private final String username;
    private final String password;
    private final AsyncResponse<List<Course>> callback;

    publicGetCoursesTask(String username, String password, AsyncResponse<List<Course>> callback) {
        this.username = username;
        this.password = password;
        this.callback = callback;
    }

    @OverrideprotectedList<Course> doInBackground(Void... voids) {
        List<Course> courses = newArrayList<Course>();

        // TODO: Some network operationtry {
            courses.addAll(getCourses(username, password));
        } catch (Exception e) {
            Log.e("GetCoursesError", e.getMessage());
        }

        return courses;
    }

    @OverrideprotectedvoidonPostExecute(List<Course> response) {
        if (callback != null) {
            callback.onResponse(response);
        }
    }
}

Notice the simple onPostExecute simply forwards along the response to the interface defined in the constructor.

Now, in your Login Activity, you can use code like this

UserLoginTaskloginTask=newUserLoginTask(
        "username",
        mPasswordView.getText().toString(),
        newAsyncResponse<Boolean>() {
            @OverridepublicvoidonResponse(Boolean response) {
                if (response) {
                    // TODO: Save data in SharedPreferenceIntentloginIntent=newIntent(LoginActivity.this, CoursesActivity.class);
                    loginIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(loginIntent);
                    finish();
                } else {
                    mPasswordView.setError("Incorrect Password");
                    mPasswordView.requestFocus();
                }
            }
        }
);
loginTask.execute();

And in the Courses Fragment

privateCourseAdapter adapter;
privateListView yourListView;
privateProgressDialog progress;

@OverridepublicViewonCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_grades, container, false);

    this.yourListView = (ListView) v.findViewById(R.id.listview);
    this.adapter = newCourseAdapter(getContext(), newArrayList<Course>());
    this.yourListView.setAdapter(adapter);

    this.progress = newProgressDialog(getContext());
    this.progress.setMessage("Loading Courses...");

    fetchCourses();

    return v;
}

privatevoidfetchCourses() {
    this.progress.show();

    GetCoursesTask getCoursesTask = newGetCoursesTask(
            "username",
            "password",
            newAsyncResponse<List<Course>>() {
                @OverridepublicvoidonResponse(List<Course> response) {
                    adapter.clear();
                    adapter.addAll(response);
                    adapter.notifyDataSetChanged();

                    progress.hide();
                }
            });
    getCoursesTask.execute();
}

Post a Comment for "Asynctask For Downloading Data And Saving Into Variable?"