01/10/2018, 00:23

Thắc mắc về AsyncTask trong Android

mình có đoạn code thế này

`public class Test{
    	  
    public static String ouput = null;

    class Task extends AsyncTask<String, Void, String>{
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            output = s;
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected String doInBackground(String... params) {
            String t = params[0];
            return t;
        }
    }

    public String result(){
        input = "day la noi dung ket qua";

        Task task = new Task();
        task.execute(input);

        return ouput;
    }
}

Mình hiểu đoạn code trên thế này:

  • khi gọi task.excute(input), thì giá trị input được truyền vào params[0] trong hàm doInBackground()
  • biến t trong hàm doInBackground() sẽ lưu lại giá trị này sau đó return t và kêt quả chuyển đến biến s trong hàm onPostExcute()
  • trong hàm onPostExcute(), có biến output (toàn cục) được gán bằng s.
  • vậy sau khi thực hiện xong task.excute ta sẽ được output = s (= “day la noi dung ket qua”);
  • và khi mình gọi đến hàm result thì kết quả phải là “day la noi dung ket qua”, nhưng thực chất kết quả lại là “null”
    m.n giải thích hộ mình tại sao kết quả lại là null. Và nếu muốn kết quả là “day la noi dung ket qua” thì phải sửa thế nào?
    mình xin cảm ơn
Nguyen Ca viết 02:32 ngày 01/10/2018

chú log ra là sẽ biết, xem cái nào chạy trước ,cái nào chạy sau,

 task.execute(input);

khi chú chạy dòng này nó đâu có đợi nó chay xong rồi mới return output đâu.

Quân viết 02:30 ngày 01/10/2018

Haha, câu hỏi kinh điển, mấy ông mới học android mà học kiểu lơ tơ mơ thì lúc nào cũng dính câu dạng này.
Đơn giản vì method AsyncTask.execute() chỉ khởi động thread ngầm, chứ k thực sự đợi thực hiện xong method doInBackground() rồi mới chuyển sang lệnh bên dưới execute. Bởi thế tên method của AsyncTask mới đặt là doInBackground (thực hiện dưới nền, còn trên nền làm gì kệ nó), và onPostResult (khi nào có kết quả thì gọi tao).
Cách sửa đơn giản nhất là call trực tiếp method cần dữ liệu output ngay bên trong method onPostResult.

bt viết 02:38 ngày 01/10/2018

mình hiểu ý bạn nói rồi, nhưng mình muốn tạo 1 biến toàn cục để lấy được kết quả đó ra (giá trị của biến s trong onPostExcute) thì phải làm thế nào?

Vũ Duy Tùng viết 02:35 ngày 01/10/2018

Vấn đề ở đây nằm ở cách bạn lấy giá trị của biến output.

Hàm Task.execute chỉ khởi động doInBackground(), và khi phần background xử lý xong thì giá trị của output mới được cập nhật. Nhưng ở phần code của bạn thì ngay sau khi khởi động doInBackground() bạn đã lấy giá trị output rồi (lúc đó hàm doInBackground() có thể chưa xử lý xong nên biến output vẫn là null).

Vậy nên nếu bạn muốn lấy giá trị output thì nên đợi cho đến khi hàm doInBackground() xử lý xong rồi mới lấy ra kết quả => lấy kết quả ở hàm onPostExcute().

Minh Nhân viết 02:34 ngày 01/10/2018

Tập xài RxAndroid luôn đi, sẽ ko bao giờ đụng đến AsyncTask nữa.

Quân viết 02:24 ngày 01/10/2018

vấn đề của bạn ấy k phải asynctask mà là làm sao để hiểu và dùng được lập trình kiểu callback/multithreading, có thể bạn ấy biết nhưng lại không vận dụng được, bạn giới thiệu 1 công nghệ mới khác nào đánh đố

Lê Vinh viết 02:36 ngày 01/10/2018

mình cũng đã từng bị như vậy :v :v :v viết hàm callback là xong…

Bài liên quan
0