[英]AsyncTask onPostExecute() is called before getting response from doInBackground() in android?
Here is my code:- 这是我的代码:
Goals.java class 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;
}
}
}
The problem is:- Before getting the response from server, the onPostExecute() function executed. 问题是:-在从服务器获取响应之前,先执行onPostExecute()函数。 So I will get empty result arraylist. 所以我将得到空结果arraylist。
JsonObjectHeader class is the basic volley class to fetch data from server. JsonObjectHeader类是从服务器获取数据的基本凌空类。
No need to use async task while you want network call by using any third party library. 当您要使用任何第三方库进行网络呼叫时,无需使用异步任务。 because the volly create its own thread for network call. 因为volly创建了自己的网络调用线程。
If you are using volley
library then remove AsyncTask
and write this code in simple method 如果使用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);
because in volley
you can get response in onResponse
so add onPostExecute
inside this 因为在volley
您可以在onResponse
获得响应,因此在此内部添加onPostExecute
Your issue is that you are creating an additional thread in your onBackground(Void...)
. 您的问题是您要在onBackground(Void...)
中创建一个附加线程。
Your code sees: 您的代码看到:
You need to use a blocking method from the Volley system. 您需要使用Volley系统中的阻止方法。 This answer explains it. 这个答案解释了它。
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) {
}
It's not your postExecute it's your 这不是您的postExecute是您的
showData();
is executed before 在执行之前
getData();
is complete. 完成了。 Ideally move your showData code to your postExecute and you will get your results as expected. 理想情况下,将showData代码移至postExecute,您将获得预期的结果。
Remove the AsyncTask. 删除AsyncTask。
Move all code from doInBackgroud in a normal function. 在正常功能中将所有代码从doInBackgroud中移出。
Call showSata() in onResponse(). 在onResponse()中调用showSata()。
I think you should read articles where is a good explanation why you should not have to use AsyncTask. 我认为您应该阅读文章,那里有一个很好的解释,为什么您不必使用AsyncTask。 My suggestion is start using Retrofit (for working with Http) + You do not have to parse JSON on your own, you can use @SerializedName annotation in your Response object 我的建议是开始使用Retrofit(用于Http)+您不必自己解析JSON,可以在Response对象中使用@SerializedName批注
Here's a tutorial demonstrates how to fetch data from server and fill recycle view 这是一个教程,演示如何从服务器获取数据并填充回收视图
Here is my code for signing in 这是我的登录代码
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());
}
});
and here is my Response class with @SerializedName annotation 这是带有@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.