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)