-2

I'm new to Android Development and I'm developing an application which has a module that pulls 'grocery' data from an API and displays it using retrofit. I've created a 'Groceries' activity for the same which is separate from the main activity. I'm trying to implement threads on the code, but my app crashes when I add a thread. It works fine without the Thread and the Handler code. The problem seems to be in either of the two. What am I doing wrong?

This question is not similar to the question "What is NullPointerException?" because I'm asking for help in the implementation of thread in this code.

The following code is from the file 'GroceriesActivity.java'.

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.ArrayList;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class GroceriesActivity extends AppCompatActivity {

    private ListView listView;
    ArrayList<GroceryItem> grocery;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            GroceryItemAdapter adapter = new GroceryItemAdapter(getApplicationContext(),R.layout.row,grocery);
            listView.setAdapter(adapter);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_groceries);

        listView = (ListView) findViewById(R.id.listView);

        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
                .create();

        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(LacClient.ENDPOINT)
                .addConverterFactory(GsonConverterFactory.create(gson));

        Retrofit retrofit = builder.build();
        final LacClient client = retrofit.create(LacClient.class);

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                Call<ArrayList<GroceryItem>> call=client.groceryList();
                call.enqueue(new Callback<ArrayList<GroceryItem>>() {

                    @Override
                    public void onResponse(Call<ArrayList<GroceryItem>> call, Response<ArrayList<GroceryItem>> response) {
                        grocery = response.body();
                    }

                    @Override
                    public void onFailure(Call<ArrayList<GroceryItem>> call, Throwable t) {

                    }
                });
                try {
                    handler.sendEmptyMessage(0);
                }catch (Exception e){}
            }
        };

        Thread fetchGroceryList = new Thread(runnable);
        fetchGroceryList.start();
    }
}

The following exception shows in the logcat.(I know this is a NullPointerException, and I know what it is. What I want to know is how to resolve it. Also the excepton shows up only when I create a thread.)

04-28 17:58:24.830 3774-3774/com.letsallchef.letsallchef E/AndroidRuntime: FATAL EXCEPTION: main
                                                                           Process: com.letsallchef.letsallchef, PID: 3774
                                                                           java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
                                                                               at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
                                                                               at android.widget.ListView.setAdapter(ListView.java:487)
                                                                               at com.letsallchef.letsallchef.GroceriesActivity$1.handleMessage(GroceriesActivity.java:25)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                               at android.os.Looper.loop(Looper.java:135)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5343)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at java.lang.reflect.Method.invoke(Method.java:372)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
Qubin
  • 1
  • 2

2 Answers2

2
call.enqueue(new Callback<ArrayList<GroceryItem>>() { already create a thread, you dont need to create yourselft.remove your  `runnable = new Runnable() {`
Linh Nguyen
  • 1,264
  • 1
  • 10
  • 22
  • Without the thread, even though the app doesn't crash, the activity does not show anything. The logcat says that xx frames have been skipped. That's why I included the thread in the first place. – Qubin Apr 28 '17 at 10:09
  • because you call your service in wrong way Call> call=client.groceryList(); give you a exception – Linh Nguyen Apr 28 '17 at 10:25
  • Do show me the right way to call it – Qubin Apr 28 '17 at 10:49
  • final LacClient client = retrofit.create(LacClient.class); client.groceryList().enqueue(new Callback>() {... – Linh Nguyen Apr 28 '17 at 10:56
  • It's the same except that I've created a reference for the Call object and you've created an anonymous object. – Qubin Apr 28 '17 at 11:25
1

grocery is null.

You are passing a null list to your array adapter.

Dishonered
  • 8,449
  • 9
  • 37
  • 50
  • Thanks @Shushobh, that helped! I took a closer look at my code and found the problem. But I had to remove the code creating a separate thread. I still need to figure out how to implement threads, but I guess that's a whole different question. – Qubin Apr 28 '17 at 12:10