0

I found a bug in my code, where the recyclerview may be null. How can I fix this?

These are the classes and code:

This is my UserListRecycler class - the main class

public class UserListRecycler extends Fragment {
    RecyclerView recyclerView;
    static UserAdapter adapter;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<UserInfo> list;


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

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.userlistGUI, container, false);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.reUsers);
        recyclerView.setHasFixedSize(true);
        list = new ArrayList<UserInfo>();
        // Instantiate new adapter here
        adapter = new MusicRecyclerAdapter(list);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);
        // Sets the adapter here
        recyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
        return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();
        populateRecyclerList();
    }


    public void populateList(){
        PopulateUsers userList = new PopulateUsers(list, adapter, recyclerView);
        userList.execute();
    }
}

This is my PopulateUsers class - where details from my server are retrieve via REST

public class PopulateUsers extends AsyncTask<String, String, String> {
    static ArrayList<UserInfo> list;
    UserAdapter adapter;
    RecyclerView recyclerView;

public PopulateUsers(ArrayList<UserInfo> list, UserAdapter adapter, RecyclerView recyclerView) {
    this.list = new ArrayList<UserInfo>(); 
    this.adapter = new UserAdapter();
    this.list = list;
    this.adapter = adapter;
    this.recyclerView = recyclerView;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(String... params) {
    // `REST` Activity happens here
}

@Override
protected void onPostExecute(String s) {
    try {
        // IT CRASHES HERE, BUT IF I INSTANTIATE A NEW LIST, 
        // THEN THIS ERROR GOES AND NOTHING IS DISPLAYED
        list.clear();  
        JSONArray jsonArray = new JSONArray(s);
        for (int i = 0; i < jsonArray.length(); i++) {
            String forename = jsonArray.getJSONObject(i).getString("forename");
            String surname = jsonArray.getJSONObject(i).getString("surname");
            String nationality = jsonArray.getJSONObject(i).getString("nationality");
            UserInfo userInfo = new UserInfo(forename, surname, nationality);
            list.add(userInfo);
        }
        // THIS LINE BELOW IS THE BIGGEST CULPRIT. IT HAS BEEN A HUGE HEADACHE
        // I EVEN TRIED THIS: adapter = new MusicRecyclerAdapter(list);
        // AND IT STILL CRASHES
        recyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

}

The adapter is NULL but how can it be friggin NULL if I have initialised it!

It keeps crashing when I call the populateList() method in another AsyncTask class - see below:

public class RecommendUsers extends AsyncTask<String, String, String> {
    @Override
    protected String doInBackground(String... params) {
        // REST stuff happens here
    }

    @Override
    protected void onPostExecute(String postData) {
        // The following line invokes the instance of `PopulateUserList` and crashes.
        // This is the culprit line
        populateList();
    }
}

This is the stack trace:

 java.lang.NullPointerException
            at lukasz.usersapp.PopulateUsers.onPostExecute(PopulateUsers.java:67)
            at lukasz.usersapp.PopulateUsers.onPostExecute(PopulateUsers.java:27)
            at android.os.AsyncTask.finish(AsyncTask.java:631)
            at android.os.AsyncTask.access$600(AsyncTask.java:177)
            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

Basically it crashes at list.clear(), but that is not an issue - I can fix, but the follow up - the recyclerView.setAdapter(adapter) is the one that is giving me a big headache. Literally driving me bonkers!!!

Would appreciate some support or solutions

In the PopulateUsers constructor, I am initialising, but I feel that the recyclerview may be NULL hence my code crashing - please see the constructor below:

public PopulateUsers(ArrayList<UserInfo> list, UserAdapter adapter, RecyclerView recyclerView) {
    this.list = new ArrayList<UserInfo>(); 
    this.adapter = new UserAdapter();
    this.list = list;
    this.adapter = adapter;
    this.recyclerView = recyclerView;
}
  • It's not good to store references of UI elements outside of the Activity/Fragment where they live. Either make the AsyncTask an inner class of the Fragment (in which case you can reference the list and adapter directly), or use an Interface listener or event bus to get the JSON results back to the Fragment. See here for the Interface listener approach: http://stackoverflow.com/questions/9963691/android-asynctask-sending-callbacks-to-ui – Daniel Nugent Feb 29 '16 at 23:13
  • Hi, even if I make it an inner class, it crashes – Lukazs Pioetrszci Feb 29 '16 at 23:58

0 Answers0