2

So I have an AsyncTask class to handle populating my RecyclerView. It works well but when it needs to be refreshed then it crashes with a NullPointerException. I kind of know why but then I can't do it because I am creating a new object and adding it to my list.

This is my code:

  @Override
        protected void onPostExecute(String s) {
            try {
                userslist.clear();
                JSONArray jsonArray = new JSONArray(s);
                for(int i=0; i < jsonArray.length(); i++){
                    ...
                    UsersData usersData = new UsersData(var1, var2);
                    userslist.add(UsersData);
                }
                cAdapter.notifyDataSetChanged(); // Culprit line, despite the list being deleted and added again in the try block
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

I suspect is it something to do with the userslist.

This is my error logs:

java.lang.NullPointerException
            at lukazs.newapp.UserInfo$GetUserList.onPostExecute(UserInfo.java:218)
            at android.os.AsyncTask.finish(AsyncTask.java:741)
            at android.os.AsyncTask.access$600(AsyncTask.java:197)
            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:654)
            at android.os.Handler.dispatchMessage(Handler.java:100)

EDIT: This is the method call where I populate the recyclerview:

public void populateRecyclerList(){
    GetUserList getUserList = new GetUserList();
    getUserList.execute();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    setContentView(R.layout.usersdetails); 
    populateRecyclerList();
    }

This is where cAdapter is initialised, in onCreate method:

RecyclerView.Adapter cAdapter;
ArrayList<UserDetailsProvider> userslist = new ArrayList<UserDetailsProvider>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    recyclerView = (RecyclerView) findViewById(R.id.recycleMusic);
    cAdapter = new UserDefinedAdapter(userslist);
    recyclerView.setAdapter(cAdapter);
    populateRecyclerList();
}

EDIT: I have done something now, but the populateRecyclerList() is crashing in another AsyncTask class on onPostExecute. Basically, I want to repopulate the recyclerView after a user has been added. This is my code for the onPostExecute() method, where I am calling the populateRecyclerList() method:

@Override
        protected void onPostExecute(String s) {
           populateRecyclerList();
        }

Maybe you are not meant to call this method here? But then how would I update the RecyclerView?

  • Maybe the only relevant part of code is missing. The exception is being fired inside onPostExecute method of AsyncTask – fillobotto Feb 26 '16 at 21:19
  • The `onPostExecute` method is there – Lukazs Pioetrszci Feb 26 '16 at 21:20
  • Any advice would be greatly appreciated – Lukazs Pioetrszci Feb 26 '16 at 21:29
  • what is at UserInfo.java line 218 – Gueorgui Obregon Feb 26 '16 at 21:34
  • @g2o ` cAdapter.notifyDataSetChanged();` – Lukazs Pioetrszci Feb 26 '16 at 21:41
  • are passing / updating the arraylist in the adapter? – UMESH0492 Feb 26 '16 at 21:43
  • Your post is misleading. Why do you include two `onCreate()` methods? Why does one have a `populate();` method and the other a `populateRecyclerList();` method? What is `populateRecyclerList();` even doing? – George Mulligan Feb 26 '16 at 22:10
  • apologies, it was a typo - it is meant to be `populateRecyclerList()`. I updated my post – Lukazs Pioetrszci Feb 26 '16 at 22:11
  • Where are you setting the layout for this activity? Did you just not include that in your post? I don't see `setContentView(...)` which might be why the lookup of your `RecyclerView` is returning null. – George Mulligan Feb 26 '16 at 22:14
  • In `onCreate` - `setContentView(R.layout.usersdetails)`; The code works but when I call it in the `asynctask` class it crashes – Lukazs Pioetrszci Feb 26 '16 at 22:18
  • You really need to just post the relevant parts of your code because it is confusing the way you are doing it in pieces. Post a single `onCreate()` with all your code and remove the other one. You might also want to include the layout file in the`recyclerView` is turning up null. – George Mulligan Feb 26 '16 at 22:31
  • You're calling `notifyDataSetChanged()` before you initialize. Your flow is incorrect. Just because you called an `AsyncTask` before you set the adapter, does not mean that the data will be ready. Instead you should initialize your `RecyclerView` set an empty adapter, and then update your adapter via callback when your `AsyncTask` is done and then call `notifyDataSetChanged()` – Pztar Feb 26 '16 at 22:33
  • I have done that though! This bug is getting on my nerves! I have done bloody everything I could - unless if I am calling the `populateRecyclerList();` in the `onPostExecute()` method in another inner AsyncTask class - I have updated my post – Lukazs Pioetrszci Feb 26 '16 at 22:58

2 Answers2

1

Your cAdapter is not initialized when you call cAdapter.notifyDataSetChanged().

EDIT: Call your populateRecyclerList() after initilize your fields

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

    recyclerView = (RecyclerView) findViewById(R.id.recycleMusic);
    cAdapter = new UserDefinedAdapter(userslist);
    recyclerView.setAdapter(cAdapter);

    populateRecyclerList();
}

Hope it helps!

Gueorgui Obregon
  • 5,077
  • 3
  • 33
  • 57
0

My bad, onPostExecute DOES run on the UI thread... Thanks you guys for correcting...

http://developer.android.com/reference/android/os/AsyncTask.html

"onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter."

Kai Wang
  • 3,303
  • 1
  • 31
  • 27