2

I am doing some asynchronous tasks with http to fetch some data.

When I close the app in the middle of an asynchronous operation, I get an a NullPointerException error. This seems to be happening because the asynchronous task is being competed and onTaskCompleted is called; But the app is already closed.

Does anyone know how to handle this?

I'm running with Android Studio, android version 4.4.2. Galaxy S4.

java.lang.NullPointerException
        at com.example.lu.seed_2.Tabs.Tab4$3.onTaskCompleted(Tab4.java:174)
        at com.example.lu.seed_2.ArticleAsync.onPostExecute(ArticleAsync.java:36)
        at com.example.lu.seed_2.ArticleAsync.onPostExecute(ArticleAsync.java:11)
        at android.os.AsyncTask.finish(AsyncTask.java:632)
        at android.os.AsyncTask.access$600(AsyncTask.java:177)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5356)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
        at dalvik.system.NativeStart.main(Native Method)

As requested, here is the onTaskComplete code

articles = convertJsonToArticles(httpResult.getBody());
articleAdapter = new ArticleAdapter(getActivity().getApplicationContext(), articles);  //<-- APP CRASHES HERE
listView = (ListView) getActivity().findViewById(R.id.mobile_list4);
listView.setAdapter(articleAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        Intent intent = new Intent(getActivity().getApplication(), WebViewActivity.class);
        intent.putExtra("_id", articles.get(i).getId());
        startActivity(intent);
    }
});
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView absListView, int scrollState) {

    }

    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        int itemsLeftCount = totalItemCount - firstVisibleItem;

        if (itemsLeftCount > 8) {
            return;
        }

        if (isLoadingMore == true) {
            return;
        }
        loadMoreArticles();
    }
});
listView.addFooterView(footerView);
showNotLoading();
v.refreshComplete();
han4wluc
  • 1,179
  • 1
  • 14
  • 26

2 Answers2

2

Maybe you should cancel all tasks in onStop(), and check if it is cancelled in doInBackground() if it's in a loop. Also check the null references.

ProtossShuttle
  • 1,623
  • 20
  • 40
1

In Additon to @ProtossShuttle answer:

As @Nguyễn Hoài Nam's comment mentioned you get a NPE if you access gui elements after the gui was destroyed.

I had the same problem and solved it like this

public class DirectoryLoaderTask extends AsyncTask<QueryParameter, Integer, IDirectory> {

    protected IDirectory doInBackground(QueryParameter... queryParameter) {
        // do heavy processing
        if (isCancelled()) return null;
        // do heavy processing
        if (isCancelled()) return null;
        // do heavy processing

        if (isCancelled()) return null;     
        // neither error nor canceld yet go on in gui
        return processingresult
    }

    protected void onPostExecute(IDirectory result) {
        if (!isCancelled() && (result != null)) {
            updateGui(result);
        }
    }
}

Before accessing the gui elements i check if it is not canceled in the beginning of onPostExecute.

k3b
  • 14,517
  • 7
  • 53
  • 85