[英]Android Retrofit : Wait for response
I am implementing retrofit 2 in my app to call web services.我正在我的应用程序中实施改造 2 以调用网络服务。 My code is as below :
我的代码如下:
SignUp.java注册.java
ConnectionDetector connectionDetector = new ConnectionDetector(SignUpActivity.this);
if (connectionDetector.isConnectingToInternet()) {
ArrayList<HashMap<String, String>> arrayListCountryDetails = new ArrayList<>();
GetCountryList getCountryList = new GetCountryList();
arrayListCountryDetails = getCountryList.CallWebServiceForCountryDetails(this);
// The app should wait here till the above retrofit web service calling returns response
CountryDetailsAdapter countryDetailsAdapter = new CountryDetailsAdapter(SignUpActivity.this, arrayListCountryDetails);
spinnerCountryName.setAdapter(countryDetailsAdapter);
} else {
String message = "No internet connection.";
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle(getResources().getString(R.string.app_name));
alertDialog.setMessage(message);
alertDialog.setCancelable(false);
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
GetCountryList.java获取国家列表.java
public class GetCountryList {
ProgressDialog dialog;
APIService mAPIService;
ArrayList<HashMap<String, String>> arrayListCountryDetails;
public ArrayList<HashMap<String, String>> CallWebServiceForCountryDetails(final Context context) {
dialog = new ProgressDialog(context);
dialog.setMessage("Please wait...");
dialog.setCancelable(false);
dialog.show();
arrayListCountryDetails = new ArrayList<>();
mAPIService = ApiUtils.getAPIService();
mAPIService.getCountryDetails().enqueue(new Callback<CountryDetailsResponseModel>() {
@Override
public void onResponse(Call<CountryDetailsResponseModel> call, Response<CountryDetailsResponseModel> response) {
if (response.isSuccessful()) {
HashMap<String, String> cntDetails = new HashMap<>();
cntDetails.put("airLineID", "0");
cntDetails.put("airLineName", "Select Airline");
arrayListCountryDetails.add(cntDetails);
// Get response
try {
if (response.body().getStatus() == 200 && response.body().getMessage().equalsIgnoreCase("success")) {
for (int count = 0; count < response.body().getCountry().size(); count++) {
cntDetails = new HashMap<>();
String countryID = response.body().getCountry().get(count).getCountryId();
String countryName = response.body().getCountry().get(count).getCountryName();
cntDetails.put("countryID", countryID);
cntDetails.put("countryName", countryName);
arrayListCountryDetails.add(cntDetails);
}
// do UI work here
if (dialog.isShowing()) {
dialog.dismiss();
}
} else {
// do UI work here
if (dialog.isShowing()) {
dialog.dismiss();
}
}
} catch (Exception e) {
// do UI work here
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
}
@Override
public void onFailure(Call<AirLineDetailsResponseModel> call, Throwable t) {
// do UI work here
if (dialog.isShowing()) {
dialog.dismiss();
}
}
});
return arrayListCountryDetails;
}
}
When i am executing the code i am getting null pointer exception error as :当我执行代码时,我收到空指针异常错误:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Spinner.setAdapter(android.widget.SpinnerAdapter)' on a null object reference
at com.abc.xyz.SignUpActivity.initializeScreen(SignUpActivity.java:176)
at com.abc.xyz.SignUpActivity.onCreate(SignUpActivity.java:147)
at android.app.Activity.performCreate(Activity.java:6575)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3121)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3278)
at android.app.ActivityThread.access$1000(ActivityThread.java:211)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1705)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6912)
at java.lang.reflect.Method.invoke(Native Method)
I know that this is because the spinner initialization execution is takes place before retrofit response.我知道这是因为微调器初始化执行发生在改造响应之前。
Please suggest me how can i wait for the retrofit response.请建议我如何等待改造响应。 What changes i need to do in above code.
我需要在上面的代码中做哪些更改。 Please i am not able to move ahead due to this issue.
由于这个问题,我无法继续前进。 Thanks in advance.
提前致谢。
Very roughly do something like the following.非常粗略地执行以下操作。 I just placed the necessary part of code inside the
AsyncTask
methods.我只是将必要的代码部分放在
AsyncTask
方法中。 Modify as necessary.根据需要进行修改。
if (connectionDetector.isConnectingToInternet()) {
// The app should wait here till the above retrofit web service calling returns response
AsyncTask task = new AsyncTask<Void, Void, List<Map<String, String>>>() {
@Override
protected String doInBackground(Void... params) {
List<Map<String, String>> arrayListCountryDetails = new ArrayList<>();
GetCountryList getCountryList = new GetCountryList();
arrayListCountryDetails = getCountryList.CallWebServiceForCountryDetails(this);
return arrayListCountryDetails;
}
@Override
protected void onPostExecute(List<Map<String, String>> arrayListCountryDetails) {
CountryDetailsAdapter countryDetailsAdapter = new CountryDetailsAdapter(SignUpActivity.this, arrayListCountryDetails);
spinnerCountryName.setAdapter(countryDetailsAdapter);
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
}
task.execute();
}
Also remove any UI calls from your GetCountryList
since this will be run on "background"同时从
GetCountryList
删除任何 UI 调用,因为这将在“后台”运行
Pass Spinner object while loading data and set adapter after load complete加载数据时传递 Spinner 对象并在加载完成后设置适配器
public class GetCountryList {
ProgressDialog dialog;
APIService mAPIService;
public void CallWebServiceForCountryDetails(final Context context,final Spinner spinnerCountryName) {
dialog = new ProgressDialog(context);
dialog.setMessage("Please wait...");
dialog.setCancelable(false);
dialog.show();
final ArrayList<HashMap<String, String>> arrayListCountryDetails = new ArrayList<>();
mAPIService = ApiUtils.getAPIService();
mAPIService.getCountryDetails().enqueue(new Callback<CountryDetailsResponseModel>() {
@Override
public void onResponse(Call<CountryDetailsResponseModel> call, Response<CountryDetailsResponseModel> response) {
if (response.isSuccessful()) {
HashMap<String, String> cntDetails = new HashMap<>();
cntDetails.put("airLineID", "0");
cntDetails.put("airLineName", "Select Airline");
arrayListCountryDetails.add(cntDetails);
// Get response
try {
if (response.body().getStatus() == 200 && response.body().getMessage().equalsIgnoreCase("success")) {
for (int count = 0; count < response.body().getCountry().size(); count++) {
cntDetails = new HashMap<>();
String countryID = response.body().getCountry().get(count).getCountryId();
String countryName = response.body().getCountry().get(count).getCountryName();
cntDetails.put("countryID", countryID);
cntDetails.put("countryName", countryName);
arrayListCountryDetails.add(cntDetails);
}
// do UI work here
if (dialog.isShowing()) {
dialog.dismiss();
}
//set Adapter
CountryDetailsAdapter countryDetailsAdapter = new CountryDetailsAdapter(context, arrayListCountryDetails);
spinnerCountryName.setAdapter(countryDetailsAdapter);
} else {
// do UI work here
if (dialog.isShowing()) {
dialog.dismiss();
}
}
} catch (Exception e) {
// do UI work here
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
}
@Override
public void onFailure(Call<AirLineDetailsResponseModel> call, Throwable t) {
// do UI work here
if (dialog.isShowing()) {
dialog.dismiss();
}
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.