0

In my android app, I'm getting some locations when I choose the first element(anyone of the list) from RecyclerView it works and it gives location normally, but when I go back to choose another one it gives me NPE.

First example:

  • I choose the second element (it works).
  • I go back to choose another one.
  • I choose the first element(gives NPE).

Second example:

  • I choose the first element (it works).

  • I go back to choose another one.

  • I choose the second element(gives NPE).

My code:

private SupportMapFragment mapFragment;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_sales_item, container, false);

    if(getArguments()!=null)
    {
        saleID = getArguments().getString("saleID");
    }

    initIDs();

   retroFit();

    maps();

    return view;
}

public void retroFit(){

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(ServiceConstants.URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    RoyalAPI royalAPI = retrofit.create(RoyalAPI.class);

    Call<SaleItemResponse> connection = royalAPI.getSaleItem(saleID);
    connection.enqueue(new Callback<SaleItemResponse>() {
        @Override
        public void onResponse(Call<SaleItemResponse> call, Response<SaleItemResponse> response) {
            List<SaleItem> posts = response.body().getData();

            latitude = posts.get(0).getLatitude();
            longitude = posts.get(0).getLongitude();


        }

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

        }
    });


}

private void map(){


    if (mapFragment == null) {
        mapFragment = SupportMapFragment.newInstance();
        mapFragment.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                LatLng latLng = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude));
                googleMap.addMarker(new MarkerOptions().position(latLng)
                        .title(""));
                googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
            }
        });
    }

    // R.id.map is a FrameLayout, not a Fragment
    getChildFragmentManager().beginTransaction().replace(R.id.map_sales, mapFragment).commit();


}

.

public class SaleItemResponse {

@SerializedName("data")
private List<SaleItem> mData;
@SerializedName("state")
private Long mState;

public List<SaleItem> getData() {
    return mData;
}

public void setData(List<SaleItem> data) {
    mData = data;
}

public Long getState() {
    return mState;
}

public void setState(Long state) {
    mState = state;
}

}

.

public class SaleItem {

@SerializedName("latitude")
private String mLatitude;
@SerializedName("longitude")


public String getLatitude() {
    return mLatitude;
}

public void setLatitude(String latitude) {
    mLatitude = latitude;
}

public String getLongitude() {
    return mLongitude;
}

public void setLongitude(String longitude) {
    mLongitude = longitude;
}
}
clauub
  • 1,134
  • 9
  • 19
Khaled
  • 238
  • 1
  • 3
  • 11
  • Please [edit] your question to provide the complete [stack trace](https://stackoverflow.com/a/23353174). – Mike M. Jan 24 '19 at 13:33
  • @MikeM. of course. – Khaled Jan 24 '19 at 13:35
  • 1
    You're not accounting for the possibility that your map will be ready before you get the response from that Retrofit call. From your description, when you go back, it seems like the map is already ready, so `onMapReady()` is called pretty much immediately, before the Retrofit call has had time to call back, so the `latitude` and `longitude` haven't been assigned yet, and are still null. – Mike M. Jan 24 '19 at 13:57
  • @MikeM. yes probably, so please, could you tell me what to edit exactly to stop this error? because i have no idea what to edit in such situation. – Khaled Jan 24 '19 at 14:07
  • 1
    Well, the first thing that comes to mind would be to move the three lines you have in `onMapReady()` into a separate method, and call that method from both `onMapReady()` and `onResponse()`. At the beginning of that method, you would first check that the map is ready, and that the coordinates are not null, before a adding the marker. You would need to make `private GoogleMap map` field in in your `Fragment`, assign that in `onMapReady()`, and check that it's not null in the new separate method. – Mike M. Jan 24 '19 at 14:18
  • 1
    @MikeM. thank you so much, really thank you so much, it works finally. – Khaled Jan 24 '19 at 14:28

0 Answers0