รอจนกว่างาน async จะเสร็จสิ้น


86

ฉันยังใหม่กับการเขียนโปรแกรมมากและฉันมีข้อสงสัย

ฉันมีAsyncTaskที่ฉันเรียกว่าRunInBackGround.

และฉันเริ่มกระบวนการนี้เช่น:

new RunInBackGround().execute();

แต่ฉันต้องการรอจนกว่าการเรียกนี้จะเสร็จสิ้นก่อนที่จะดำเนินการตามคำสั่งอื่น ๆ ของรหัส

ฉันจะทำเช่นนั้นได้อย่างไร?

มีวิธีใดบ้าง?


2
จุดของ AsyncTask คือ Asynchronous ซึ่งหมายความว่าจะไม่ซิงโครไนซ์กับส่วนที่เหลือของโค้ด
Gjordis

3
คุณสามารถใช้เมธอด onPostExecute () ของ AsyncTask เพื่อรับการโทรกลับในคลาสของคุณ
DcodeChef

5
คุณไม่ต้องการรอจนกว่าจะเสร็จ สิ่งที่คุณต้องการคือทราบเมื่อเสร็จสิ้น
njzk2

3
@DcodeChef เป็นคนเดียวที่เข้าใจสิ่งที่เขาต้องการในคำถามนี้
Please_Dont_Bully_Me_SO_Lords

1
ฉันคิดว่านี่คือคำตอบคุณกำลังมองหา stackoverflow.com/questions/13079645/…
user3362415

คำตอบ:


131

รอจนกว่าสายนี้จะดำเนินการเสร็จสิ้น

คุณจะต้องเรียกใช้วิธีAsyncTask.get ()เพื่อรับผลลัพธ์กลับมาและรอจนกว่าdoInBackgroundการดำเนินการจะไม่เสร็จสมบูรณ์ แต่จะหยุดด้ายหลัก UI ถ้าคุณไม่ได้รับการเรียกวิธีการภายในด้าย

ในการรับผลลัพธ์กลับในUI เธรดเริ่มต้นAsyncTaskด้วย:

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

3
แล้วจะรอผลยังไงไม่ให้เธรด UI หลักล็อก?! พูดว่ารหัสกำลังรอผลลัพธ์ แต่ในขณะนั้นแถบความคืบหน้าจะหมุนต่อไป!
Muhammad Naderi

2
@MuhammadNaderi: ใช้AsyncTaskโดยไม่ใช้getวิธีและในonPostExecuteวิธีAsyncTask เรียกว่าซึ่งให้ผลลัพธ์ u บนเธรด UI หลัก
ρяσѕρєя K

3
แน่ใจว่านี่เป็นวิธีแก้ปัญหาซึ่งฉันใช้มาระยะหนึ่งแล้ว แต่บางครั้งฉันต้องการรหัสเพื่อรอ asynctask บางอย่างเช่นawaitในc#และไม่ได้รับเธรดหลักถูกล็อกแน่นอน
Muhammad Naderi

2
@ ρяσѕρєяKขอบคุณขอบคุณล้าน คุณไม่รู้หรอกว่าฉันดึงผมออกจากปัญหานี้มากแค่ไหน แต่มีเพียงอันเดียว. get () มันแก้ไขได้ (คุณล้อเล่นฉัน) เพียงอันเดียว. get () !!!!!
Code_Worm

คุณจะใช้ AsyncTask และหลีกเลี่ยงการใช้ get () เพื่อหลีกเลี่ยงไม่ให้ UI ค้างได้อย่างไร
Arjun Issar

37

แม้ว่าในทางที่ดีจะเป็นเรื่องดีหากโค้ดของคุณสามารถทำงานแบบขนานได้ แต่อาจเป็นกรณีที่คุณใช้เธรดดังนั้นคุณจึงไม่บล็อกเธรด UI แม้ว่าขั้นตอนการใช้งานแอปของคุณจะต้องรอก็ตาม

คุณมี 2 ตัวเลือกที่นี่

  1. คุณสามารถรันโค้ดที่คุณต้องการรอได้ใน AsyncTask เอง หากเกี่ยวข้องกับการอัปเดต UI (เธรด) คุณสามารถใช้เมธอด onPostExecute ระบบจะเรียกสิ่งนี้โดยอัตโนมัติเมื่อทำงานเบื้องหลังเสร็จ

  2. หากคุณถูกบังคับให้ทำใน Activity / Fragment / Whatever ด้วยเหตุผลบางประการคุณสามารถทำให้ตัวเองเป็นผู้ฟังที่กำหนดเองได้ซึ่งคุณถ่ายทอดจาก AsyncTask ของคุณ ด้วยการใช้สิ่งนี้คุณสามารถมีวิธีการโทรกลับใน Activity / Fragment / Whatever ที่จะเรียกเมื่อคุณต้องการเท่านั้น: aka เมื่อ AsyncTask ของคุณทำอะไรก็ได้ที่คุณต้องรอ


6
นี่เป็นคำตอบที่ยอดเยี่ยมควรเป็นคำตอบที่ได้รับการยอมรับ และนี่คือตัวอย่างวิธีการบรรลุเป้าหมายนี้ด้วย AsyncTasks: stackoverflow.com/questions/12575068/…
Jose Gonzalez

ในตัวเลือกที่สองของคุณในเวลาที่คุณส่งเจตนาไปยังผู้รับของคุณเธรดหลักจะกลับมาทำงานต่อทันที OP ไม่ต้องการสิ่งนั้น
LincyTonita

16

ในการAsyncTaskเพิ่ม ProgressDialog ของคุณเช่น:

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

คุณสามารถ setMessage ในonPreExecute()วิธีการเช่น:

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

และในonPostExecute(Void result)วิธีการของคุณปิดProgressDialogไฟล์.


15

AsyncTask มีสี่วิธี ..

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.

คุณสามารถโทรหางานของคุณonPostExecute()ได้หลังจากกลับจากdoInBackground()

onPostExecute คือสิ่งที่คุณต้องใช้ในการดำเนินการ


1

ฉันคิดว่าวิธีที่ง่ายที่สุดคือการสร้างอินเทอร์เฟซเพื่อรับข้อมูลจาก onpostexecute และเรียกใช้ Ui จากอินเทอร์เฟซ:

สร้างอินเทอร์เฟซ:

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

จากนั้นใน asynctask

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

จากนั้นในกิจกรรมหลักของคุณ

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

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.