0

Hi I'm new to Retrfoit 2. I want to fetch data using Retrofit 2.My API retrieves data in JSON Format. I'm sending parameter to API through the app. API is working fine when I tested it in browser. I'm getting on a null object reference but I have checked all things.

This is what I tried.

Model class

public class Detail {

@SerializedName("PromoId")
@Expose
private String PromoId;

@SerializedName("PromoName")
@Expose
private String PromoName;

@SerializedName("Category")
@Expose
private String Category;

@SerializedName("PromoImg")
@Expose
private String PromoImg;

@SerializedName("compName")
@Expose
private String compName;


public String getCompName() {
    return compName;
}

public void setCompName(String compName) {
    this.compName = compName;
}


public String getPromoId() {
    return PromoId;
}

public void setPromoId(String promoId) {
    PromoId = promoId;
}

public String getPromoName() {
    return PromoName;
}

public void setPromoName(String promoName) {
    PromoName = promoName;
}

public String getCategory() {
    return Category;
}

public void setCategory(String category) {
    Category = category;
}

public String getPromoImg() {
    return PromoImg;
}

public void setPromoImg(String promoImg) {
    PromoImg = promoImg;
}}

Api Client

public class ApiClient {

public static final String BASE_URL = "http://example.com";
public static Retrofit retrofit = null;


public static Retrofit getApiClient (){

    if(retrofit==null){
        retrofit = new Retrofit.Builder().baseUrl(BASE_URL).
                addConverterFactory(GsonConverterFactory.create()).build();

    }

    return retrofit;
}}

Api Interface

public interface ApiInterface {


    @POST("/api/customer/{PromoId}")
    Call<Detail> getReponse(@Path("PromoId") String PromoId) ;
}

Main Activity

public class MainActivity extends Activity {

private ApiInterface apiInterface;


TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tv = (TextView)findViewById(R.id.textView);

    getDataForId("3");
}

public void getDataForId(final String id){
    apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
    Call<Detail> call = apiInterface.getReponse(id);
    call.enqueue(new Callback<Detail>() {


        @Override
        public void onResponse(Call<Detail> call, Response<Detail> response) {

            final Detail myResponse = response.body();
            Toast.makeText(getApplicationContext(), "Inside on Response", Toast.LENGTH_SHORT).show();

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    tv=(TextView)findViewById(R.id.textView);
                    tv.setText(myResponse.getCategory());
                }
            });


        }

        @Override
        public void onFailure(Call<Detail> call, Throwable t) {
            Toast.makeText(getApplicationContext(), "Failed", Toast.LENGTH_SHORT).show();
        }


    });}}
venura
  • 125
  • 2
  • 15
  • can you please add an interceptor for log the request https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor and post the logs – tebitoq Sep 19 '17 at 19:53
  • Where is the null pointer exception occurring? – nasch Sep 19 '17 at 21:21
  • @nasch- myResponse getting null. tv.setText(myResponse.getCategory()); gets null. But in web service it has value java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String abc.com.test.Detail.getCategory()' on a null object reference – venura Sep 20 '17 at 04:04
  • @venura you don't need `runOnUiThread`. some logs should help. check interceptors for logginh – Raghunandan Sep 20 '17 at 06:22

1 Answers1

0

As @Raghunandan mentioned runOnUiThread is not necessary, your are already making the call asynchronously.

But usually you get null here for 2 reasons:

  1. An issue in retrieving JSON from the API (you've confirmed that API returns the correct JSON)

  2. An issue in parsing the JSON (more likely)

If you are using Android Studio 3, you can debug this in the Network view in the Android Studio Profiler, to see if your app is retrieving the JSON object, as described here: https://futurestud.io/tutorials/retrofit-2-analyze-network-traffic-with-android-studio-profiler

If you're not using Android Studio 3, you might want to use OkHttp interceptor (this will display the JSON in your logs): https://www.learn2crack.com/2016/06/retrofit-okhttp-logging-interceptor.html Make sure to remove it before you publish your app though.

if you don't see the JSON in the logs, then your issue is (1) described above depending on your real BASE_URL you might want to look at the placement of the / in @POST("/api/customer/{PromoId}") , not sure if this is the problem, but then retrofit is very particular about the position of / as described here: https://futurestud.io/tutorials/retrofit-2-url-handling-resolution-and-parsing

If you can see the JSON in the logs then the issue is (2), usually the issue in this case is:

  • Malformed pojos
  • Incompatible version of JSON converter, in your case GsonConverterFactory, make sure that you're importing compatible versions in your build.gradle

good luck

ninjayoto
  • 693
  • 1
  • 7
  • 14
  • .Thank you very much for the nice explantation. In the above scenario it goes to onResponse method. I have used OkHttp interceptor and I found that there's an issue called 405 Method Not Allowed. Then I changed the POST method to GET. Now app is not crashing. But it goes to onFailure section. In the log it shows that JSON output retrieves without any issue. Do u have any idea? – venura Sep 20 '17 at 08:41
  • Glad you're getting your JSON now. So you're dealing with issue (2) , what error are you getting? it can be due to malformed pojos, check your `Details` class and the associated classes, make sure they map well to the JSON you're getting. – ninjayoto Sep 20 '17 at 09:22
  • I checked this with a log. It's not the problem 2. It's getting java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $ issue. That's mean I'm getting this array in a wrongway? – venura Sep 20 '17 at 09:27
  • Oh, ok then look here: https://stackoverflow.com/questions/33621808/why-does-gson-fromjson-throw-a-jsonsyntaxexception-expected-some-type-but-was-s – ninjayoto Sep 20 '17 at 09:28