0

This is my AsyncTask:

public class GetDataTask extends AsyncTask<Void, Void, JSONArray> {

        @Override
        protected void onPreExecute() {
            // [...]
        }

        @Override
        protected void onPostExecute(JSONArray result) {

            int result_length = 0;

            try {
                result_length = result.length();
            } catch (NullPointerException e) {
                e.printStackTrace();

                // Redirect the user back to the original activity
                Intent intent = new Intent(ResultActivity.this, MainActivity.class);
                startActivity(intent);
            }


            for (int i = 0; i < result_length; i++) {
                // [...]
            }
        }

        @Override
        protected JSONArray doInBackground(Void... params) {
            // [...]
        }
}

When result is null, .length() throws a NullPointerException. That's why I want to redirect the url back to MainActivity when this happen.

try {
    result_length = result.length();
} catch (NullPointerException e) {
    e.printStackTrace();

    // Redirect the user back to the original activity
    Intent intent = new Intent(ResultActivity.this, MainActivity.class);
    startActivity(intent);

The problem is that it doesn't work. I get e.printStackTrace() but the activity doesn't change. It's like Intent is not "fast" enough to change activity, and the code below (for (int i = 0; i < result_length; i++) {}) still keeps running.
What can I do? Is my solution wrong? Thank you in advance.

  • I think async task is a thread, that's why the `for` loop executes even after facing exception. So you have to cancel your `AsyncTask` as soon as you get error(i.e in `catch` block). – Kaushal28 Feb 26 '17 at 16:47

3 Answers3

0

In the AsyncTask contructor provide the Activity reference.

private Activity activity;

public GetDataTask (Activity activity) {
   this.activity = activity;
}

then you can call it like this

activity.startActivity(new Intent(activity, MainActivity.class));
Mikhail Kim
  • 559
  • 7
  • 18
0

It's like Intent is not "fast" enough to change activity

When you launch an activity via startActivity(), you are not immediately spawning that action. You are just kindly asking the framework to launch the specified activity for you. And it doesn't mean, that after startActivity() the code below it wouldn't be called. The executor will continue to execute the code until the end of scope. If you want to stop execution afterward you have to return immediately after startActivity().

azizbekian
  • 60,783
  • 13
  • 169
  • 249
0

Personally, catch (NullPointerException ) is always wrong. Plus if (variable == null) is arguably faster.

AsyncTask should just return; or stop, not necessarily start anything.

Another suggestion: Make sure that doInBackground returns an empty JSONArray instead of null.

and the code below (for (int i = 0; i < result_length; i++) {}) still keeps running

Sure, because the for loop is not inside the try block...

try {
    result_length = result.length();
} catch (NullPointerException e) {
    e.printStackTrace();

    // Redirect the user back to the original activity
    Intent intent = new Intent(ResultActivity.this, MainActivity.class);
    startActivity(intent);
}

// The result is still null here...

Replace all catching with a simpler null check and simply don't let the loop be entered.

@Override
protected void onPostExecute(JSONArray result) {

    int result_length = result == null ? 0 : result.length();

    for (int i = 0; i < result_length; i++) {
        // This loop won't run when the result is null... 
    }

If you really want to, then check if (result_length == 0), but again, the Activity should be called back to when the result finishes, and then you can start some other activity.

Ref: How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

Community
  • 1
  • 1
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245