How do I fix a java.lang.NullPointerException
on my for loop. I am guessing I am not getting a value at list_location.size()
and Also, a NPE on sharePreferences onBackground. What I'm trying to do is to plot all markers on postExecute and store it's data on sharedpreferences while its running onBackground.
Question, how do I get the value of list_location that was added here
list_location.add(new LocationHolder(lat, lng, location, remarks));
on my onBackground and get it at onPostExecute?
public class SnailTrailFragment extends Fragment implements OnMapReadyCallback {
private ProgressDialog pDialog;
ArrayList<LocationHolder> list_location;
public static GoogleMap mMapSnailTrail;
public static String baseUrl = "http://mark.journeytech.com.ph/mobile_api/";
public static NetworkAPI networkAPI;
Context context;
static Activity activity;
public SnailTrailFragment(Context c, Activity a) {
context = c;
activity = a;
}
public interface NetworkAPI {
@POST("snailtrail.php")
@Headers({"Content-Type:application/json; charset=UTF-8"})
Call<JsonElement> loginRequest(@Body SnailTrailPojo body);
}
public static class SnailTrailPojo {
String platenum;
String datetimefrom;
String datetimeto;
String client_table;
public SnailTrailPojo(String platenum, String datetimefrom, String datetimeto, String client_table) {
this.platenum = platenum;
this.datetimefrom = datetimefrom;
this.datetimeto = datetimeto;
this.client_table = client_table;
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_contact_us, container, false);
return v;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map1);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMapSnailTrail = googleMap;
new GetSnailTrail().execute();
mMapSnailTrail.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(12.405888, 123.273419), 6));
}
class GetSnailTrail extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
networkAPI = retrofit.create(NetworkAPI.class);
SnailTrailPojo loginRequest = new SnailTrailPojo(vm.getPlate_num(), /*"08/03/2017 00:00:00"*/ BottomSheetModalFragment.dateFrom, "08/04/2017 23:59:59", client_table);
System.out.println(vm.getPlate_num() + client_table + BottomSheetModalFragment.dateFrom + " asdas");
Call<JsonElement> call = networkAPI.loginRequest(loginRequest);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
// success response
if (response.body().isJsonArray()) {
JsonArray objectWhichYouNeed = response.body().getAsJsonArray();
// System.out.println(response.body() + " "+ "Response");
list_location = new ArrayList<>();
for (int i = 0; i < response.body().getAsJsonArray().size(); i++) {
JsonElement location_array = response.body().getAsJsonArray().get(i);
JsonObject location_obj = location_array.getAsJsonObject();
String location = location_obj.get("location").toString();
JsonElement lat_array = response.body().getAsJsonArray().get(i);
JsonObject lat_obj = lat_array.getAsJsonObject();
String lati = lat_obj.get("lat").toString();
String latiString = lati;
latiString = latiString.replace("\"", "");
String lat = String.valueOf(latiString);
JsonElement lng_array = response.body().getAsJsonArray().get(i);
JsonObject lng_obj = lng_array.getAsJsonObject();
String longi = lng_obj.get("lng").toString();
String longiString = longi;
longiString = longiString.replace("\"", "");
String lng = String.valueOf(longiString);
JsonElement remarks_array = response.body().getAsJsonArray().get(i);
JsonObject remarks_obj = remarks_array.getAsJsonObject();
String remarks = remarks_obj.get("remarks").toString();
if (lat != null && !lat.equals("null") && (lng != null && !lng.equals("null"))) {
list_location.add(new LocationHolder(lat, lng, location, remarks));
}
SharedPreferences preferences = context.getSharedPreferences("AppPrefs", MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = preferences.edit();
Gson gson = new Gson();
String jsonText = gson.toJson(list_location);
prefsEditor.putString("key", jsonText);
prefsEditor.commit();
}
} else {
System.out.println("Not a JSONArray.");
}
}
@Override
public void onFailure(Call<JsonElement> call, Throwable t) {
// failure response
System.out.println("Fail " + call.toString());
}
});
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
final PolylineOptions polylineOptions = new PolylineOptions();
for (int j = 0; j < list_location.size(); j++) {
// Setting the color of the polyline
polylineOptions.color(Color.RED);
// Setting the width of the polyline
polylineOptions.width(3);
Double d1 = Double.parseDouble(list_location.get(j).getLatitude());
Double d2 = Double.parseDouble(list_location.get(j).getLongitude());
Toast.makeText(getContext(), d1 + d2.toString(),Toast.LENGTH_LONG).show();
// Setting points of polyline
polylineOptions.add(new LatLng(d1, d2));
createMarker(j, d1, d2, list_location.get(j).getRemarks());
}
// Adding the polyline to the map
mMapSnailTrail.addPolyline(polylineOptions);
/* Gson gson = new Gson();
SharedPreferences myPrefs;
myPrefs = context.getSharedPreferences("AppPrefs", MODE_PRIVATE);
String jsonText = myPrefs.getString("key", null);
Type collectionType = new TypeToken<List<LocationHolder>>(){}.getType();
List<LocationHolder> addArray= (List<LocationHolder>) new Gson()
.fromJson( jsonText , collectionType);*/
}
}
public void createMarker(int index, Double latitude, Double longitude, String snippet) {
// Adding the taped point to the ArrayList
BitmapDescriptor image = BitmapDescriptorFactory.fromResource(R.drawable.bus);
mMapSnailTrail.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.anchor(0.5f, 0.5f)
.title(snippet)
.snippet(snippet)
.icon(image));
mMapSnailTrail.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 15.0f));
mMapSnailTrail.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
marker.hideInfoWindow();
}
});
}
public class MarkerInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
public MarkerInfoWindowAdapter() {
}
@Override
public View getInfoWindow(Marker marker) {
return null;
}
@Override
public View getInfoContents(final Marker marker) {
View v = getActivity().getLayoutInflater().inflate(R.layout.marker_popup, null);
Button b = (Button) v.findViewById(R.id.button2);
b.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
marker.hideInfoWindow();
}
});
TextView markerLabel = (TextView) v.findViewById(R.id.textView2);
markerLabel.setText("");
return v;
}
}
}
Logs
java.lang.NullPointerException at com.journeytech.mark.mark.fragment.SnailTrailFragment$GetSnailTrail.onPostExecute(SnailTrailFragment.java:227) at com.journeytech.mark.mark.fragment.SnailTrailFragment$GetSnailTrail.onPostExecute(SnailTrailFragment.java:122) 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:136) at android.app.ActivityThread.main(ActivityThread.java:5021) 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:827) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
Here's the second log
java.lang.NullPointerException at com.journeytech.mark.mark.fragment.SnailTrailFragment$GetSnailTrail$1.onResponse(SnailTrailFragment.java:212) at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5021) 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:827)
Problem:
You are using retrofit to get reponse using enqueue which asynchronously sends the request.
No what you are doing is calling enqueue
asynchronously, and there is no need for it. Your AsyncTask
finishes before you get your response in onResponse
and when you make a for loop inside your postExecute
you get null pointer becuase the list is not updated yet and you try to access it.
@Override
public void onMapReady(GoogleMap googleMap) {
mMapSnailTrail = googleMap;
// Remove asynctask since you are already using retrofit enqueue
// new GetSnailTrail().execute();
//Create a new method to call api using retrofit
getDataFromServer();
mMapSnailTrail.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(12.405888, 123.273419), 6));
}
private void getDataFromServer() {
/**
*Show Progress dialog here
*/
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
networkAPI = retrofit.create(NetworkAPI.class);
SnailTrailPojo loginRequest = new SnailTrailPojo(vm.getPlate_num(), /*"08/03/2017 00:00:00"*/ BottomSheetModalFragment.dateFrom, "08/04/2017 23:59:59", client_table);
System.out.println(vm.getPlate_num() + client_table + BottomSheetModalFragment.dateFrom + " asdas");
Call<JsonElement> call = networkAPI.loginRequest(loginRequest);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
// success response
/**
* Hide the progress dialog here
*/
if (response.body().isJsonArray()) {
JsonArray objectWhichYouNeed = response.body().getAsJsonArray();
// System.out.println(response.body() + " "+ "Response");
list_location = new ArrayList<>();
for (int i = 0; i < response.body().getAsJsonArray().size(); i++) {
JsonElement location_array = response.body().getAsJsonArray().get(i);
JsonObject location_obj = location_array.getAsJsonObject();
String location = location_obj.get("location").toString();
JsonElement lat_array = response.body().getAsJsonArray().get(i);
JsonObject lat_obj = lat_array.getAsJsonObject();
String lati = lat_obj.get("lat").toString();
String latiString = lati;
latiString = latiString.replace("\"", "");
String lat = String.valueOf(latiString);
JsonElement lng_array = response.body().getAsJsonArray().get(i);
JsonObject lng_obj = lng_array.getAsJsonObject();
String longi = lng_obj.get("lng").toString();
String longiString = longi;
longiString = longiString.replace("\"", "");
String lng = String.valueOf(longiString);
JsonElement remarks_array = response.body().getAsJsonArray().get(i);
JsonObject remarks_obj = remarks_array.getAsJsonObject();
String remarks = remarks_obj.get("remarks").toString();
if (lat != null && !lat.equals("null") && (lng != null && !lng.equals("null"))) {
list_location.add(new LocationHolder(lat, lng, location, remarks));
}
SharedPreferences preferences = context.getSharedPreferences("AppPrefs", MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = preferences.edit();
Gson gson = new Gson();
String jsonText = gson.toJson(list_location);
prefsEditor.putString("key", jsonText);
prefsEditor.commit();
//Move the on postExecute code here
final PolylineOptions polylineOptions = new PolylineOptions();
for (int j = 0; j < list_location.size(); j++) {
// Setting the color of the polyline
polylineOptions.color(Color.RED);
// Setting the width of the polyline
polylineOptions.width(3);
Double d1 = Double.parseDouble(list_location.get(j).getLatitude());
Double d2 = Double.parseDouble(list_location.get(j).getLongitude());
Toast.makeText(getContext(), d1 + d2.toString(),Toast.LENGTH_LONG).show();
// Setting points of polyline
polylineOptions.add(new LatLng(d1, d2));
createMarker(j, d1, d2, list_location.get(j).getRemarks());
}
// Adding the polyline to the map
mMapSnailTrail.addPolyline(polylineOptions);
}
} else {
System.out.println("Not a JSONArray.");
}
}
@Override
public void onFailure(Call<JsonElement> call, Throwable t) {
// failure response
System.out.println("Fail " + call.toString());
}
});
}