Android NullPointerException в ответе Retrofit - PullRequest
2 голосов
/ 18 февраля 2020

В моей деятельности у меня есть более одной операции сервисов Retrofit, и эти сервисы ретранслируют одни и те же методы обратного вызова Retrofit. И это вызывает нулевой указатель, когда одна служба пытается получить обратный вызов в то же время, когда обратный вызов используется другим сервисом, как решить эту проблему?

Я использовал модификацию для своих вызовов веб-сервиса. Он работает нормально в эмуляторе, но когда я использую реальное устройство, он падает и получает журнал ошибок как:

  java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
    at com.itmam.info.jadara.Notifications.Notifications_Items_Adapter$4.onResponse(Notifications_Items_Adapter.java:309)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
    at android.os.Handler.handleCallback(Handler.java:888)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:213)
    at android.app.ActivityThread.main(ActivityThread.java:8147)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)

Это мой класс клиента Retrofit:

public class RetrofitGeneral {

private static Retrofit retrofit;
private static final String BASE_URL = "My_URL";

public static Retrofit getRetrofitInstance() {
    if (retrofit == null) {
        retrofit = new retrofit2.Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
 }
}

Это мой Интерфейс службы модернизации:

public interface getClientDetails {
@FormUrlEncoded
@POST("WebService.asmx/SelectClientById")
Call<List<ClientDetails>> getClientdetails(
        @Field("ClientID") int ClientID,
        @Field("Token") String Token,
        @Field("CurrentEmployeeID") int CurrentEmployeeID
 );
}

И таким образом я выполняю вызов службы модернизации из моего адаптера onBindViewHolder, который вызывает модификацию более одного раза:

@Override
public void onBindViewHolder(Notifications_Items_Adapter.Notifications_Holder holder, int position) {
    myHolder = holder;
    holderList.add(holder);
    getTaskId(position);
    getTaskDetails(taskID);

}

Это моя модернизация Метод обратного вызова:

private void getTaskDetails(int taskID){
    getTaskDetails getTaskDetails=RetrofitGeneral.getRetrofitInstance().create(getTaskDetails.class);
    Call<List<Task>> listCall=getTaskDetails.getDetails(taskID,Log_in.getToken(),Log_in.CurrentEmployeeID);
    listCall.enqueue(new Callback<List<Task>>(){
        @Override
        public void onResponse(Call<List<Task>> call, Response<List<Task>> response) {
            task = response.body().get(0); // Error here after the second call. 
            tasksList.add(task);
        }

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

        }
    });
}

Пожалуйста, помогите:)

Ответы [ 3 ]

2 голосов
/ 18 февраля 2020

Проблема была устранена с помощью Retrofit Synchronous, например:

UserService service = ServiceGenerator.createService(UserService.class);

// 1. Calling '/api/users/2' - synchronously

Call<UserApiResponse> callSync = service.getUser(2);

try
{
  Response<UserApiResponse> response = callSync.execute();
  UserApiResponse apiResponse = response.body();

  //API response
  System.out.println(apiResponse);
} 
catch (Exception ex) 
{ 
  ex.printStackTrace();
}

из Retrofit 2 - Пример синхронного и асинхронного вызова .

2 голосов
/ 18 февраля 2020

Ошибка из-за этой строки

Toast.makeText(context, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();

listCall.enqueue выполняет сетевой вызов в фоновом потоке, и вы не можете отобразить тост из фонового потока, вы должны используйте Main thread для отображения тоста.

Вы можете использовать

runOnUiThread(new Runnable() {
Toast.makeText(context, "Something went wrong...Please try later!",Toast.LENGTH_SHORT).show();
}

, чтобы исправить ошибку.

Для ответа, почему ваш вызов не удался, вы можете распечатать трассировку стека. чтобы понять это

 @Override
    public void onFailure(Call<List<Task>> call, Throwable t) {
        t.printStackTrace();
        runOnUiThread(new Runnable() {
        Toast.makeText(context, "Something went wrong...Please try later!",Toast.LENGTH_SHORT).show();
       }
    }
1 голос
/ 18 февраля 2020
public void onResponse(Call<SalaryListModel> call, Response<SalaryListModel> 
response) {

 if (response.isSuccessful()) {

    Log.e(TAG, "onResponse: calling");

 if (response.body().getStatus_code() == 200) {

    Log.e(TAG, "onResponse: calling 200");

            }

        } else {
            Log.e(TAG, "onResponse: else--");
            if (response.code() == 500) {
                Log.e(TAG, "onResponse: 500");

                //and if you want to parse your error body try this

                /*
                try {
                    Gson gson = new Gson();
                    YourErrorClass error = gson.fromJson(response.errorBody().charStream(), YourErrorClass.class);

                } catch (Exception e) {
                     Log.e(TAG, "onResponse error: " + e.getMessage());
                }*/



            } else if (response.code() == 406) {
                Log.e(TAG, "onResponse: 406");
            } else {
                Log.e(TAG, "onResponse: esle");
            }

        }

    }
...