Retrofit 从 Web 获取数据会抛出空对象引用
Retrofit getting data from web throws null object reference
我正在尝试从 Web 获取数据 api 但出了点问题,我无法弄明白。
我的JSON看起来像这样
{
"partners":
[
"partner1",
"partner2",
"partner3",
... ,
"partner150"
]
}
我有 Table 个合作伙伴 (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 模型 class:
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();
}
这是我的API帮手class
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;
}
}
这是 Fragment,我有一个 Button,我想在该 Button 上实现 onClick 方法以从 API 获取数据并将其保存到合作伙伴 table。
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) {
APIHelper helper = new APIHelper();
helper.getApiService();
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());
/*if (response.body() != null) {
ArrayList<String> partnersList;
partnersList = response.body();
Log.d("DOWNLOAD", String.valueOf(partnersList));
}*/
}
@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) {
}
}
这是我的问题。一切正常,没有错误,但是当我点击按钮时没有任何反应。
所以我想我犯了一些错误,但我想不通(第一次进行改造)。
我想要的按钮点击是从网络上获取所有合作伙伴并将其保存到我的合作伙伴 table。
问题:有人可以指导我并告诉我哪里出了问题并帮助我解决这个问题吗?
编辑:
Button.OnClickListener btnListener = (new View.OnClickListener() {
@Override
public void onClick(View v) {
APIHelper helper = new APIHelper();
apiService = helper.getApiService();
Call<ArrayList<String>> call = null;
call.enqueue(new Callback<ArrayList<String>>() {
@Override
public void onResponse(Call<ArrayList<String>> call, Response<ArrayList<String>> response) {
ArrayList<String> partners = response.body();
Log.d(TAG, "Number of partners received: " + partners.size());
}
@Override
public void onFailure(Call<ArrayList<String>> call, Throwable t) {
Toast.makeText(getActivity(), "FAIL!!!", Toast.LENGTH_SHORT).show();
}
});
}
});
错误日志:
Error:(68, 60) error: is not abstract and does not
override abstract method
onResponse(Call>,Response>) in
Callback
Error:(72, 53) error: cannot find symbol method body()
Error:(69, 17) error: method does not override or implement a method
from a supertype
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
Compilation failed; see the compiler error output for details.
根据您的 JSON 回复,您的 POJO class 应该是:
public class Partners {
private ArrayList<String> partners = new ArrayList<>(0);
// Get; Set methods //
}
您的问题出在 onClick()
helper.getApiService();
您没有将服务分配到变量中
将其更改为:
apiService = helper.getApiService();
编辑:
基于新的更新,我认为你不需要使用 POJO
只需在 Call
中使用以下内容
Call<ArrayList<String>>
并且要获得响应只需使用 response.body()
而不使用 .partners()
.
尝试在代码中的任何地方替换它并检查
尝试将其放入您的 APIHelper class 以获取有关您发送的内容的更多信息
public static APIService apiService;
//this http loggin interceptor allows you debug requests and responses
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
// add your other interceptors …
// add logging as last interceptor
httpClient.addInterceptor(logging); // <-- this is the important line!
public static APIService getApiService() {
if (apiService == null) {
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}
return apiService;
}
可能是您发送信息的方式不对...
请记住,在服务器端,您必须对接收到的信息进行解码(使用 json_decode)。
我正在尝试从 Web 获取数据 api 但出了点问题,我无法弄明白。
我的JSON看起来像这样
{
"partners":
[
"partner1",
"partner2",
"partner3",
... ,
"partner150"
]
}
我有 Table 个合作伙伴 (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 模型 class:
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();
}
这是我的API帮手class
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;
}
}
这是 Fragment,我有一个 Button,我想在该 Button 上实现 onClick 方法以从 API 获取数据并将其保存到合作伙伴 table。
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) {
APIHelper helper = new APIHelper();
helper.getApiService();
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());
/*if (response.body() != null) {
ArrayList<String> partnersList;
partnersList = response.body();
Log.d("DOWNLOAD", String.valueOf(partnersList));
}*/
}
@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) {
}
}
这是我的问题。一切正常,没有错误,但是当我点击按钮时没有任何反应。
所以我想我犯了一些错误,但我想不通(第一次进行改造)。
我想要的按钮点击是从网络上获取所有合作伙伴并将其保存到我的合作伙伴 table。
问题:有人可以指导我并告诉我哪里出了问题并帮助我解决这个问题吗?
编辑:
Button.OnClickListener btnListener = (new View.OnClickListener() {
@Override
public void onClick(View v) {
APIHelper helper = new APIHelper();
apiService = helper.getApiService();
Call<ArrayList<String>> call = null;
call.enqueue(new Callback<ArrayList<String>>() {
@Override
public void onResponse(Call<ArrayList<String>> call, Response<ArrayList<String>> response) {
ArrayList<String> partners = response.body();
Log.d(TAG, "Number of partners received: " + partners.size());
}
@Override
public void onFailure(Call<ArrayList<String>> call, Throwable t) {
Toast.makeText(getActivity(), "FAIL!!!", Toast.LENGTH_SHORT).show();
}
});
}
});
错误日志:
Error:(68, 60) error: is not abstract and does not override abstract method onResponse(Call>,Response>) in Callback
Error:(72, 53) error: cannot find symbol method body()
Error:(69, 17) error: method does not override or implement a method from a supertype
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
Compilation failed; see the compiler error output for details.
根据您的 JSON 回复,您的 POJO class 应该是:
public class Partners {
private ArrayList<String> partners = new ArrayList<>(0);
// Get; Set methods //
}
您的问题出在 onClick()
helper.getApiService();
您没有将服务分配到变量中 将其更改为:
apiService = helper.getApiService();
编辑:
基于新的更新,我认为你不需要使用 POJO
只需在 Call
Call<ArrayList<String>>
并且要获得响应只需使用 response.body()
而不使用 .partners()
.
尝试在代码中的任何地方替换它并检查
尝试将其放入您的 APIHelper class 以获取有关您发送的内容的更多信息
public static APIService apiService;
//this http loggin interceptor allows you debug requests and responses
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
// add your other interceptors …
// add logging as last interceptor
httpClient.addInterceptor(logging); // <-- this is the important line!
public static APIService getApiService() {
if (apiService == null) {
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}
return apiService;
}
可能是您发送信息的方式不对... 请记住,在服务器端,您必须对接收到的信息进行解码(使用 json_decode)。