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
Bài liên quan
chú log ra là sẽ biết, xem cái nào chạy trước ,cái nào chạy sau,
khi chú chạy dòng này nó đâu có đợi nó chay xong rồi mới return output đâu.
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.
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ấ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().
Tập xài RxAndroid luôn đi, sẽ ko bao giờ đụng đến AsyncTask nữa.
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 đố
mình cũng đã từng bị như vậy :v :v :v viết hàm callback là xong…