Android - Мой onPostExecute в AsyncTask не вызывается - PullRequest
0 голосов
/ 02 января 2019

Итак, я пытался получить объекты JSON в моем Django REST Framework API.Алгоритм для этого вызывается в onPostExecute моего AsyncTask, но кажется, что он вызывается не так, как при отладке, он не идет туда.Кажется, что в моем logcat нет ничего фатального, кроме того, что в моем массиве нет ничего, что могло бы содержать данные из API DRF.

У меня есть два действия, которые вызывают мой AsyncTask из моего класса WSAdapter.Один предназначен для входа в систему, а другой - для отображения всех сообщений после входа в систему.

Вход в систему работает нормально, но перечисление сообщений - нет.

Мой код указан ниже:

Posts.java

public class Posts extends AppCompatActivity {

    TextView postsSect;
    Button postsDoneBtn;
    WSAdapter.SendAPIRequests PostsHelper;
    StringBuilder postsBuffer = new StringBuilder();

    @Override
    protected void onResume(){
        super.onResume();
        PostsDetails postDetailsHelper = new PostsDetails();
        postDetailsHelper.ListPosts();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_posts);

        PostsDetails postDetailsHelper = new PostsDetails();

        postsDoneBtn = (Button) findViewById(R.id.PostsDoneButton);

        postDetailsHelper.callPostDetails("192.168.0.18:8000/api");
        postDetailsHelper.ListPosts();
        postDetailsHelper.postDetailsCalled('n');

        postsDoneBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Posts.this, MainActivity.class));

            }
        });
    }

    public class PostsDetails {
        //String post_title, post_content;
        ArrayList<Integer> post_id = new ArrayList<Integer>();
        ArrayList<String> post_title = new ArrayList<String>();
        ArrayList<String> post_content = new ArrayList<String>();

        boolean isPDCalled;

        // sets if Post details are called
        boolean postDetailsCalled(char called) {
            if (called == 'y'){
                return true;
            }
            return false;
        }

        // checks if postsDetails functions are called for AsyncTask
        boolean getIsPDCalled(){
            return isPDCalled;
        }

        // calls the execute for AsyncTask
        private void callPostDetails(String theurl){
            PostsHelper = new WSAdapter.SendAPIRequests();
            // sets if post details are called
            postDetailsCalled('y');
            // executes AsyncTask
            PostsHelper.execute(theurl);
        }

        // sets values for the posts arrays
        public void setPost(int p_id, String p_title, String p_content) {
            post_id.add(p_id);
            post_title.add(p_title);
            post_content.add(p_content);
        }

        // Lists the posts from the database
        public void ListPosts() {
            /////////// add functionality if a post was deleted and was clicked
            postsSect = (TextView) findViewById(R.id.PostsSection);
            postsSect.setText(post_title.get(post_title.size()) + "\n");
            for (int i = post_id.size() - 1; i > 0; i--)
            {
                postsSect.append(post_title.get(i));
            }
        }
    }
}

WSAdapter.java

public class WSAdapter extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    static public class SendAPIRequests extends AsyncTask<String, String, String> {

        // Add a pre-execute thing

        @Override
        protected String doInBackground(String... params) {

            Log.e("TAG", params[0]);
            Log.e("TAG", params[1]);
            String data = "";

            HttpURLConnection httpURLConnection = null;
            try {

                // Sets up connection to the URL (params[0] from .execute in "login")
                httpURLConnection = (HttpURLConnection) new URL(params[0]).openConnection();

                // Sets the request method for the URL
                httpURLConnection.setRequestMethod("POST");

                // Tells the URL that I am sending a POST request body
                httpURLConnection.setDoOutput(true);

                // To write primitive Java data types to an output stream in a portable way
                DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
                // Writes out a byte to the underlying output stream of the data posted from .execute function
                wr.writeBytes("postData=" + params[1]);
                // Flushes the postData to the output stream
                wr.flush();
                wr.close();

                // Representing the input stream
                InputStream in = httpURLConnection.getInputStream();

                // Preparing input stream bytes to be decoded to charset
                InputStreamReader inputStreamReader = new InputStreamReader(in);
                StringBuilder dataBuffer = new StringBuilder();

                // Translates input stream bytes to charset
                int inputStreamData = inputStreamReader.read();
                while (inputStreamData != -1) {
                    char current = (char) inputStreamData;
                    inputStreamData = inputStreamReader.read();
                    // concatenates data characters from input stream
                    dataBuffer.append(current);
                }
                data = dataBuffer.toString();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // Disconnects socket after using
                if (httpURLConnection != null) {
                    httpURLConnection.disconnect();
                }
            }

            Log.e("TAG", data);
            return data;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            // expecting a response code fro my server upon receiving the POST data
            Log.e("TAG", result);

            Posts.PostsDetails postsHelper = new Posts().new PostsDetails();

            // For posts
            try {
                if (postsHelper.getIsPDCalled()){
                    JSONObject pJObj = new JSONObject(result);
                    JSONArray pJObjArray = pJObj.getJSONArray("posts");

                    for (int i = 0; i < pJObjArray.length(); i++) {
                        JSONObject pJObj_data = pJObjArray.getJSONObject(i);
                        postsHelper.setPost(pJObj_data.getInt("id"), "post_title", "post_content");
                    }
                }

            } catch (JSONException e) {
                //Toast.makeText(JSonActivity.this, e.toString(), Toast.LENGTH_LONG).show();
                Log.d("Json","Exception = "+e.toString());
            }
        }
    }
}

Login.java

public class Login extends AppCompatActivity {

    Button LoginButton;
    EditText uUserName, uPassWord;
    WSAdapter.SendAPIRequests AuthHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        //SetupHomeBtn = (ImageButton) findViewById(R.id.SetupHomeBtn);

        LoginButton = (Button) findViewById(R.id.LoginButton);

        uUserName = (EditText) findViewById(R.id.LoginUserBox);
        uPassWord = (EditText) findViewById(R.id.LoginPassBox);

        //AuthHelper = new WSAdapter().new SendDeviceDetails();

        // Moves user to the main page after validation
        LoginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // gets the username and password from the EditText
                String strUserName = uUserName.getText().toString();
                String strPassWord = uPassWord.getText().toString();

                // API url duh
                String APIUrl = "http://192.168.0.18:8000/token-auth/";

                // If the user is authenticated, then transfer to the MainActivity page
                if (APIAuthentication(strUserName, strPassWord, APIUrl)){
                    startActivity(new Intent(Login.this, Posts.class));
                }
            }
        });

    }

    private boolean APIAuthentication(String un, String pw, String url){
        // when it wasn't static -> AuthHelper = new WSAdapter().new SendAPIRequests();
        AuthHelper = new WSAdapter.SendAPIRequests();

        JSONObject postData = new JSONObject();
        try {
            // Attempt to input info to the Django API
            postData.put("username", un);
            postData.put("password", pw);

            // Putting the data to be posted in the Django API
            AuthHelper.execute(url, postData.toString());

            return true;
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return false;
    }
}

Я ожидал, что мой onPostExecute будет вызван и сохраненданные для моих постов массивов.

1 Ответ

0 голосов
/ 02 января 2019

Хорошо, это хороший пример асинхронных задач.Проблема здесь в том, что когда вы вызываете асинхронную задачу, приведенный ниже код будет продолжать выполняться, даже если асинхронная задача еще не завершена.Итак, что происходит в вашем случае:

  • Вы получаете сообщения, а затем просите отобразить их в тот момент, когда функция асинхронизации все еще получает сообщения.Конечно, список пуст.

Это можно исправить с помощью ключевого слова await.Это ключевое слово останавливает выполнение остальной части вашего кода до тех пор, пока эта строка не будет выполнена.Поэтому измените:

postDetailsHelper.callPostDetails("192.168.0.18:8000/api");

на:

await postDetailsHelper.callPostDetails("192.168.0.18:8000/api");

Теперь причина того, что вход в систему работает, заключается в том, что вы вызываете эту функцию в операторе if.Если вы сначала сохраните возвращаемое значение этой функции в логическом значении, то оно тоже не будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...