2016-08-18 34 views
-2

我试图从Web API获取数据,但在我的onResponse()方法中出现错误,我找不到它。改造onResponse方法不工作,抛出NullPointerException

我的JSON看起来像这样

[ 
    "partner1", 
    "partner2", 
    "partner3", 
    ...  , 
    "partner150" 
    ] 

我有表的合作伙伴(ActiveAndroid)中,我想保存来自API的所有合作伙伴。

@Table(name = "Partners") 
public class Partners extends Model { 

    @Column(name = "Name") 
    String name; 

    public Partners() {} 

    public Partners(String name) { 
     this.name = name; 
    } 
} 

这里是我的POJO模型类:

public class Partners extends ArrayList<String> { 

@SerializedName("partners") 
@Expose 
public List<String> partners = new ArrayList<String>(); 

public List<String> getPartners() { 
    return partners; 
} 

public void setName(List<String> partners) { 
    this.partners = partners; 
} 

}

这是我的接口

public interface APIService { 

     @GET("Partners") 
     Call<Partners> getPartners(); 
} 

这是我APIHelper类

public class APIHelper { 

    public static final String PARTNERS_URL = "https://part-of-link.com/partners.json/"; 

    public static APIService apiService; 

    public static APIService getApiService() { 
     if (apiService == null) { 
      Retrofit retrofit = new Retrofit.Builder().baseUrl(PARTNERS_URL) 
        .addConverterFactory(GsonConverterFactory.create()).build(); 
      apiService = retrofit.create(APIService.class); 
     } 
     return apiService; 
    } 
} 

这是片段,我有一个按钮,我想在其上执行onClick()方法以从API获取数据并将其保存到合作伙伴表中。

public class DownloadMain extends Fragment implements Callback<Partners> { 

    private Button dloadPartners; 
    private Call<Partners> callPartners; 
    public static APIService apiService; 

    public DownloadMain() {} 

    public DownloadMain newInstance() { return new DownloadMain(); } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     View view = inflater.inflate(R.layout.download_main, container, false); 

     dloadPartners = (Button) view.findViewById(R.id.downloadPartners); 
     dloadPartners.setOnClickListener(btnListener); 

     callPartners = APIHelper.getApiService().getPartners(); 
     callPartners.enqueue(this); 

     return view; 
    } 

    Button.OnClickListener btnListener = (new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      APIHelper helper = new APIHelper(); 
      apiService = helper.getApiService(); 

      Call<Partners> call = apiService.getPartners(); 
      call.enqueue(new Callback<Partners>() { 
       @Override 
       public void onResponse(Call<Partners> call, Response<Partners> response) { 

     Call<Partners> call = apiService.getPartners(); 
     call.enqueue(new Callback<Partners>() { 
      @Override 
      public void onResponse(Call<Partners> call, Response<Partners> response) { 

       List<String> partners = response.body().getPartners(); 
       Log.d(TAG, "Number of partners received: " + partners.size()); 
       } 

       @Override 
       public void onFailure(Call<Partners> call, Throwable t) { 
        Toast.makeText(getActivity(), "FAIL!!!", Toast.LENGTH_SHORT).show(); 
       } 
      }); 
     } 
    }); 
    @Override 
    public void onResponse(Call<Partners> call, Response<Partners> response) { 


    } 

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

    } 
} 

这里onResponse()方法引发我一个错误:Attempt to invoke virtual method 'java.util.List com.example...pojo.Partners.getPartners()' on a null object reference

我想要的是让来自网络的所有合作伙伴,并保存到我的合作伙伴表上按一下按钮。

我找不到这个错误的解决方案,所以如果有人可以帮助我,我将不胜感激。

问题:有人可以指导我,告诉我什么是错的,并帮助我解决这个问题吗?

+0

什么是JSON响应的完整模式?由于您使用GSON将JSON映射到POJO,我怀疑您可能错误地声明了POJO。 – crymson

+0

@crymson JSON在我的网页API URL看起来像这样'[ “合作伙伴1”, “合作伙伴2”, “partner3”, ......, “partner150” ]' – RubyDigger19

+0

我只是想指出的是,你连续调用你的Retrofit方法两次...并且根本不需要合作伙伴类 –

回答

1

首先,Java命名约定。 Partner表示单个实体,不是Partners的复数。 - 改变你的类名来反映这一点。这也让我们感到困惑,因为你的问题有两个同名的类。对于你的用例,创建一个扩展Arraylist的类是不必要的。


其次,请学习适当的JSON到Java的转换。你的JSON只是一个字符串数组 - 扩展Arraylist的对象再次是不必要的。

如果你想保持ActiveAndroid模型对象,并用它来改造,将JSON需要像这样一个List<Partner>

[ 
    {"name": "partner1"}, 
    {"name": "partner2"} 
] 

而对于与内部的ArrayList延伸的ArrayList中的电流Partners类,这样的事情(这是不正确的JSON)

[ 
    "partners" : [ 
     "partner1", 
     "partner2" 
    ] 
] 

所以,你再也不需要扩展Arraylist的类。


最后,试着理解改进方法用法的“流程”。

你得到一个Call对象的某种类型,你enqueue它启动HTTP请求,然后你定义Callback有两个动作,当请求成功和错误。

现在,看看你已经实现了片段上的回调?

public class DownloadMain extends Fragment implements Callback<Partners> 

但你需要使用该 - 你有onResponseonError在片段类的底部... 这就是,你应该实现在改造完成后会发生什么那两个空的方法,而这也正是代码去当你有onCreateView

callPartners.enqueue(this); 

这条线,但因为这些方法都是空的,什么都不会发生的这一呼吁。与此同时,其他enqueue方法有不必要的Callback方式,当你可以只使用this

此外,没有进攻,但你似乎只是复制粘贴代码周围不知道发生了什么......注意,你如何做一个第二,不必要的API调用。

// Call 1 
Call<Partners> call = apiService.getPartners(); 
call.enqueue(new Callback<Partners>() { 
    @Override 
    public void onResponse(Call<Partners> call, Response<Partners> response) { 
     // Call 2, despite having a response 
     Call<Partners> call = apiService.getPartners(); 
     call.enqueue(new Callback<Partners>() { 
      @Override 
      public void onResponse(Call<Partners> call, Response<Partners> response) { 

所有这些上述问题,我不是太惊讶改造会出错误,但可以通过先固定的改造模式来避免这个问题,那么一定要检查是否response.body()是空尝试之前用它。


如果你做得正确,onClick中唯一的代码行就是这个。

callPartners.enqueue(DownloadMain.this); 
+0

感谢您的回答。我已经做了你所说的一切,但在onClick方法我得到'callPartners.enqueue(this)错误;'并且不知道什么是错的? – RubyDigger19

+0

我无法猜测在该行可能发生的所有错误,那么错误到底在说什么? –

+0

这里是错误'错误:(61,25)错误:接口调用中的方法入队不能应用于给定的类型; 找到:<匿名OnClickListener>' – RubyDigger19

0

在按钮点击侦听器中,尽管您调用helper.getApiService();但apiService未初始化。因此,当调用Call call = apiService.getPartners();时,apiService实例为null。因此NullPointerException。

初始化apiService。

@Override 
public void onClick(View v) { 
    APIHelper helper = new APIHelper(); 
    apiService = helper.getApiService(); 

    Call<Partners> call = apiService.getPartners(); 
+0

它被初始化但不工作..getting'试图调用接口方法'int java.util.List。大小()'在空对象引用上' – RubyDigger19

0

好像你的JSON响应只是一个字符串数组,所以我觉得你可以用POJO的废除,而是这样做:

public interface APIService { 

    @GET("Partners") 
    Call<List<String>> getPartners(); 
} 

同时更换所有类型的参数,你宣布PartnersList<String>为例,全部替换为Call<Partners>Call<List<String>>

+0

我做了像你说的,但现在我得到了'尝试调用接口方法'int java.util.List.size()'在一个空对象引用'on this line Log.d(TAG,“收到的合作伙伴数量:”+ partners.size());'你知道也许是什么问题? – RubyDigger19

相关问题