Chờ cho đến khi tác vụ không đồng bộ kết thúc công việc của nó


84

Tôi là người mới lập trình và tôi có một số nghi ngờ.

Tôi có một AsyncTaskcái mà tôi gọi là RunInBackGround.

và tôi bắt đầu quá trình này như:

new RunInBackGround().execute();

Nhưng tôi muốn đợi cho đến khi lệnh gọi này kết thúc quá trình thực thi, trước khi tiếp tục các câu lệnh khác của mã.

Làm thế nào tôi có thể làm điều đó?

Có cách nào cho nó?


2
Điểm của AsyncTask là nó không đồng bộ, có nghĩa là nó không được đồng bộ hóa với phần còn lại của mã.
Gjordis

3
Bạn có thể sử dụng phương thức onPostExecute () của AsyncTask của nó để nhận lệnh gọi lại trong lớp của bạn.
DcodeChef

5
bạn không thực sự muốn đợi cho đến khi nó hoàn thành. Những gì bạn muốn là biết khi nào nó kết thúc.
njzk2

3
@DcodeChef là người duy nhất hiểu anh ấy muốn gì trong câu hỏi.
Please_Dont_Bully_Me_SO_Lords

1
Tôi nghĩ rằng đây là câu trả lời bạn đang tìm kiếm stackoverflow.com/questions/13079645/...
user3362415

Câu trả lời:


129

đợi cho đến khi cuộc gọi này kết thúc thực thi

Bạn sẽ cần gọi phương thức AsyncTask.get () để lấy lại kết quả và đợi cho đến khi quá trình doInBackgroundthực thi không hoàn tất. nhưng điều này sẽ đóng băng chuỗi Main UI nếu bạn không gọi phương thức get bên trong một Chủ đề .

Để nhận lại kết quả trong Chuỗi giao diện người dùng, hãy bắt đầu AsyncTasknhư:

String str_result= new RunInBackGround().execute().get();

3
vậy làm thế nào để đợi kết quả và không bị khóa chuỗi UI chính ?! nói mã chờ kết quả nhưng trong thời gian này, thanh tiến trình tiếp tục lăn!
Muhammad Naderi

2
@MuhammadNaderi: Sử dụng AsyncTaskmà không cần getphương pháp và trong AsyncTask onPostExecutephương pháp được gọi là cung cấp u quả trên Main UI Chủ đề
ρяσѕρєя K

3
chắc chắn đây là một cách giải quyết, mà tôi đã được sử dụng trong một thời gian bây giờ, nhưng đôi khi tôi cần cho các mã để chờ cho AsyncTask, một cái gì đó giống như awaittrong c#, và không nhận được các chủ đề chính khóa tất nhiên
Muhammad Naderi

2
@ ρяσѕρєяK cảm ơn bạn, cảm ơn một triệu. bạn không biết tôi đã giải quyết vấn đề này bao nhiêu nhưng chỉ với một .get () nó đã giải quyết được (bạn đùa với tôi) duy nhất một .get () !!!!!
Code_Worm

Làm cách nào bạn có thể sử dụng AsyncTask và tránh sử dụng get () để tránh giao diện người dùng bị đóng băng?
Arjun Issar

37

Mặc dù tối ưu sẽ rất tốt nếu mã của bạn có thể chạy song song, có thể là trường hợp bạn chỉ đơn giản là sử dụng một chuỗi để bạn không chặn chuỗi giao diện người dùng, ngay cả khi quy trình sử dụng ứng dụng của bạn sẽ phải đợi nó.

Bạn có khá nhiều 2 lựa chọn ở đây;

  1. Bạn có thể thực thi mã bạn muốn, trong AsyncTask chính nó. Nếu phải cập nhật giao diện người dùng (luồng), bạn có thể sử dụng phương thức onPostExecute. Điều này được gọi tự động khi công việc nền của bạn hoàn thành.

  2. Nếu vì lý do nào đó, bạn buộc phải làm điều đó trong Activity / Fragment / Anything, bạn cũng có thể tự biến mình thành trình nghe tùy chỉnh mà bạn phát từ AsyncTask của mình. Bằng cách sử dụng điều này, bạn có thể có một phương thức gọi lại trong Hoạt động / Phân đoạn / Bất cứ thứ gì chỉ được gọi khi bạn muốn: hay còn gọi là khi AsyncTask của bạn được thực hiện với bất kỳ thứ gì bạn phải chờ đợi.


6
Đây là một câu trả lời tuyệt vời, nên được chấp nhận. Ngoài ra, đây là một ví dụ về cách đạt được điều này với AsyncTasks: stackoverflow.com/questions/12575068/…
Jose Gonzalez,

trong tùy chọn thứ hai của bạn, Trong thời gian có nghĩa là bạn đưa ra ý định cho bộ thu của mình, luồng chính sẽ được tiếp tục lại ngay. OP không cần điều đó.
LincyTonita

16

Trong AsyncTaskthêm một ProgressDialog của bạn như:

private final ProgressDialog dialog = new ProgressDialog(YourActivity.this);

bạn có thể setMessage trong onPreExecute()phương thức như:

this.dialog.setMessage("Processing..."); 
this.dialog.show();

và trong onPostExecute(Void result)phương pháp của bạn, loại bỏ của bạn ProgressDialog.


15

AsyncTask có bốn phương thức ..

onPreExecute  -- for doing something before calling background task in Async

doInBackground  -- operation/Task to do in Background

onProgressUpdate  -- it is for progress Update

onPostExecute  -- this method calls after asyncTask return from doInBackground.

bạn có thể gọi công việc của mình trên onPostExecute()đó gọi sau khi trở về từdoInBackground()

onPostExecute là những gì bạn cần Triển khai.


1

Tôi nghĩ cách dễ nhất là tạo một giao diện để lấy dữ liệu từ onpostexecute và chạy Ui từ giao diện:

Tạo giao diện:

public interface AsyncResponse {
    void processFinish(String output);
}

Sau đó, trong asynctask

@Override
protected void onPostExecute(String data) {
    delegate.processFinish(data);
}

Sau đó, trong hoạt động chính của bạn

@Override
public void processFinish(String data) {
     // do things

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.