[英]Android AsyncTask - onPostExecute called before doInBackground finishes
[英]AsyncTask onPostExecute() is called before getting response from doInBackground() in android?
這是我的代碼:
Goals.java類
public class Goals extends AppCompatActivity{
private ArrayList<Goal> result;
private RecyclerView.Adapter adapter;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private ArrayList<Goal> dataFromServer;
private Toolbar toolbar;
//This is for back button
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
startActivity(new Intent(this, MainActivity.class));
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.goal_list);
recyclerView=(RecyclerView) findViewById(R.id.goal_recycler_view);
toolbar=(Toolbar) findViewById(R.id.toolbar);
recyclerView.setHasFixedSize(true);
layoutManager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
setSupportActionBar(toolbar);
//FOr back button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
//fetch goal list from server and also its related action
getData();
//Send Data to GoalAdaptor
showData();
}
private void showData() {
Log.i("Show Date","Enter");
System.out.println("Result Array List"+result.toString());
adapter=new goalAdaptor(this, result);
recyclerView.setAdapter(adapter);
}
private void getData() {
result=new ArrayList<>();
DownloadPlansFromServer server= new DownloadPlansFromServer();
server.execute();
}
class DownloadPlansFromServer extends AsyncTask<Void,Void,Boolean>
{
private ProgressDialog progressDialog;
Boolean planActive=false;
protected void onPreExecute() {
// NOTE: You can call UI Element here.
//UI Element
progressDialog = new ProgressDialog(Goals.this);
progressDialog.setMessage("Downloading Plans Data..");
progressDialog.show();
}
@Override
protected Boolean doInBackground(Void... params) {
try {
Response.Listener listener=new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response) {
try {
System.out.println("Inside the response");
// Parsing json object response
// response will be a json object
System.out.println("Output is "+response.toString());
//Toast.makeText(getApplicationContext(),response.toString(),Toast.LENGTH_LONG).show();
planActive=response.getBoolean("success");
if (planActive)
{
JSONArray plansArray=response.getJSONArray("response");
//get Plans Details
for (int p=0;p<plansArray.length();p++)
{
JSONObject plan=plansArray.getJSONObject(p);
//get Goals Details
JSONObject planGoals=plan.getJSONObject("goal");
Goal goal=new Goal();
goal.setGoal_name("Goal Name:- "+planGoals.getString("goal_name"));
Log.i("Goal Name is",planGoals.getString("goal_name"));
JSONObject currentValue=planGoals.getJSONObject("current_value");
JSONObject targetValue=planGoals.getJSONObject("target_value");
//Get the values parameter
ArrayList<String> parameterList=getTheParameter(planGoals.getString("goal_id"));
if (parameterList.isEmpty())
{
System.out.println("Problem WHile Processing the parameter ");
}
else
{
String goalDescription="Reduce the value from";
StringBuilder currentStringBuilder=new StringBuilder();
for (int k=0;k<parameterList.size();k++)
{
currentStringBuilder.append(currentValue.getString(parameterList.get(k))+"/");
}
StringBuilder targetStringBuilder=new StringBuilder();
for (int k=0;k<parameterList.size();k++)
{
targetStringBuilder.append(targetValue.getString(parameterList.get(k))+"/");
}
goal.setGoal_description(goalDescription+currentStringBuilder.toString()+" to "+ targetStringBuilder.toString());
}
//Add the result to the array
result.add(goal);
}
}
}
catch (JSONException k)
{
Log.i("On Response",k.getMessage());
k.printStackTrace();
}
}
};
Response.ErrorListener errorListener=new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle Error
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
error.printStackTrace();
Toast.makeText(getApplicationContext(), " this Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof AuthFailureError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "User not authorized", Toast.LENGTH_SHORT).show();
} else if (error instanceof ServerError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Server error", Toast.LENGTH_SHORT).show();
} else if (error instanceof NetworkError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof ParseError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Error consuming request", Toast.LENGTH_SHORT).show();
}
else error.printStackTrace();
}
};
String plan_url=Constants.url+"plan";
JsonObjectHeader customRequest=new JsonObjectHeader(plan_url,null, listener, errorListener);
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(customRequest);
System.out.println("After custom Request");
planActive=true;
}catch (Exception e)
{
e.printStackTrace();
}
return planActive;
}
protected void onPostExecute(Boolean unused) {
// NOTE: You can call UI Element here.
// Close progress dialog
progressDialog.dismiss();
if (unused)
{
Log.i("Get Plan","Yes");
//showData();
}
else
Toast.makeText(getApplicationContext(),"No Plans Found",Toast.LENGTH_LONG).show();
}
}
private ArrayList<String> getTheParameter(String goal_id) {
ArrayList<String> arrayList=new ArrayList<>();
if (goal_id.equals("bp"))
{
arrayList.add("systolic");
arrayList.add("diastolic");
return arrayList;
}
else
{
arrayList.add(null);
return arrayList;
}
}
}
問題是:-在從服務器獲取響應之前,先執行onPostExecute()函數。 所以我將得到空結果arraylist。
JsonObjectHeader類是從服務器獲取數據的基本凌空類。
當您要使用任何第三方庫進行網絡呼叫時,無需使用異步任務。 因為volly創建了自己的網絡調用線程。
如果使用volley
庫,則刪除AsyncTask
並以簡單方法編寫此代碼
try {
Response.Listener listener=new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response) {
try {
System.out.println("Inside the response");
// Parsing json object response
// response will be a json object
System.out.println("Output is "+response.toString());
//Toast.makeText(getApplicationContext(),response.toString(),Toast.LENGTH_LONG).show();
planActive=response.getBoolean("success");
if (planActive)
{
JSONArray plansArray=response.getJSONArray("response");
//get Plans Details
for (int p=0;p<plansArray.length();p++)
{
JSONObject plan=plansArray.getJSONObject(p);
//get Goals Details
JSONObject planGoals=plan.getJSONObject("goal");
Goal goal=new Goal();
goal.setGoal_name("Goal Name:- "+planGoals.getString("goal_name"));
Log.i("Goal Name is",planGoals.getString("goal_name"));
JSONObject currentValue=planGoals.getJSONObject("current_value");
JSONObject targetValue=planGoals.getJSONObject("target_value");
//Get the values parameter
ArrayList<String> parameterList=getTheParameter(planGoals.getString("goal_id"));
if (parameterList.isEmpty())
{
System.out.println("Problem WHile Processing the parameter ");
}
else
{
String goalDescription="Reduce the value from";
StringBuilder currentStringBuilder=new StringBuilder();
for (int k=0;k<parameterList.size();k++)
{
currentStringBuilder.append(currentValue.getString(parameterList.get(k))+"/");
}
StringBuilder targetStringBuilder=new StringBuilder();
for (int k=0;k<parameterList.size();k++)
{
targetStringBuilder.append(targetValue.getString(parameterList.get(k))+"/");
}
goal.setGoal_description(goalDescription+currentStringBuilder.toString()+" to "+ targetStringBuilder.toString());
}
//Add the result to the array
result.add(goal);
}
}
}
catch (JSONException k)
{
Log.i("On Response",k.getMessage());
k.printStackTrace();
}
}
};
Response.ErrorListener errorListener=new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle Error
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
error.printStackTrace();
Toast.makeText(getApplicationContext(), " this Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof AuthFailureError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "User not authorized", Toast.LENGTH_SHORT).show();
} else if (error instanceof ServerError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Server error", Toast.LENGTH_SHORT).show();
} else if (error instanceof NetworkError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT).show();
} else if (error instanceof ParseError) {
//TODO
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Error consuming request", Toast.LENGTH_SHORT).show();
}
else error.printStackTrace();
}
};
String plan_url=Constants.url+"plan";
JsonObjectHeader customRequest=new JsonObjectHeader(plan_url,null, listener, errorListener);
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(customRequest);
因為在volley
您可以在onResponse
獲得響應,因此在此內部添加onPostExecute
您的問題是您要在onBackground(Void...)
中創建一個附加線程。
您的代碼看到:
您需要使用Volley系統中的阻止方法。 這個答案解釋了它。
RequestFuture<JSONObject> future = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(Method.POST, SIGNUP_URL, reqBody, future, future)
volleyRequestQueue.add(request);
try {
JSONObject response = future.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
這不是您的postExecute是您的
showData();
在執行之前
getData();
完成了。 理想情況下,將showData代碼移至postExecute,您將獲得預期的結果。
刪除AsyncTask。
在正常功能中將所有代碼從doInBackgroud中移出。
在onResponse()中調用showSata()。
我認為您應該閱讀文章,那里有一個很好的解釋,為什么您不必使用AsyncTask。 我的建議是開始使用Retrofit(用於Http)+您不必自己解析JSON,可以在Response對象中使用@SerializedName批注
這是一個教程,演示如何從服務器獲取數據並填充回收視圖
這是我的登錄代碼
Call<LoginResponse> call = retrofit.create(ComeAroundAPIInterface.class).signin(data);
call.enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.isSuccessful()) {
onLoginSuccess();
sharedPreferences = getSharedPreferences(LOGIN_COOKIE, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("LOGIN",true);
editor.commit();
progressDialog.dismiss();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("user", (LoginResponse)response.body());
startActivity(intent);
finish();
} else {
progressDialog.cancel();
onLoginFailed();
Converter<ResponseBody, APIError> converter = retrofit.responseBodyConverter(APIError.class, new Annotation[0]);
APIError error = new APIError();
try {error = converter.convert(response.errorBody());} catch (IOException e) {}
Toast.makeText(getBaseContext(),error.message(),Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
onLoginFailed();
Log.e("Login", t.toString());
}
});
這是帶有@SerializedName批注的我的Response類
public class LoginResponse implements Parcelable{
@SerializedName("id")
private String id;
@SerializedName("username")
private String username;
@SerializedName("email")
private String email;
@SerializedName("name")
private String name;
@SerializedName("sirname")
private String sirname;
//getters
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.