简体   繁体   English

从Android的doInBackground()获得响应之前调用AsyncTask onPostExecute()吗?

[英]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: 您的代码看到:

  1. Start onPreExecute. 启动onPreExecute。
  2. Show Dialog. 显示对话框。
  3. Return from onPreExecute. 从onPreExecute返回。
  4. Start onBackground. 在背景上启动。
  5. New thread created by Volley Request (Thread #2) 排球请求创建的新线程(线程2)
  6. Return from onBackground. 从onBackground返回。
  7. Start onPostExecute. 启动onPostExecute。
  8. Close Dialog. 关闭对话框。
  9. Return from onPostExecute. 从onPostExecute返回。
  10. Return from Thread #2. 从线程#2返回。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM