【问题标题】:Android NullPointerException in Retrofit response改造响应中的 Android NullPointerException
【发布时间】:2020-06-02 06:23:25
【问题描述】:

在我的活动中,我有多个改造服务操作,这些服务依赖于相同的改造回调方法。并且当一个服务尝试获取回调同时回调被其他服务使用时,这些会导致空指针,如何解决这个问题?

我一直在为我的网络服务调用使用改造。它在模拟器中运行良好,但是当我使用真实设备时它崩溃并得到错误日志:

  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)

这是我的改造客户端类:

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) {

        }
    });
}

请帮忙:)

【问题讨论】:

  • 在我的活动中,我有多个改造服务操作,这些服务依赖于相同的改造回调方法。并且当一个服务尝试获取回调同时回调被其他服务使用时,这些会导致空指针,如何解决这个问题?
  • 您在代码中使用的列表上出现空指针异常。请确保在调用该列表上的任何函数之前初始化该列表。我看到您在代码中使用的列表不止一个。请使用日志中显示的行号检查导致错误的列表。
  • 所有列表在调用任何函数之前初始化,错误由task = response.body().get(0);因为响应返回 null,代码为 500。@DeepakRai
  • 就像我说的,在调用列表中的任何方法时需要确定。 response.body() 返回一个列表,您在其上调用 get(0) 而不检查它是否为空。此外,由于内部服务器错误,您会得到 500 的空值。确认您的呼叫请求正确或与您的后端开发人员讨论。

标签: android api callback nullpointerexception retrofit


【解决方案1】:

错误是因为这一行

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

listCall.enqueue 在后台线程上进行网络调用,您无法从后台线程显示 toast,您必须使用主线程来显示 toast。

你可以使用

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();
       }
    }

【讨论】:

  • 嗨,运行时异常已解决,但我遇到了另一个异常:java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)'在空对象引用上
【解决方案2】:

通过使用 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 – Synchronous and asynchronous call example

【讨论】:

    【解决方案3】:
    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");
                }
    
            }
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-22
      • 2015-10-24
      • 1970-01-01
      • 2019-06-20
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多