ตัวจัดการ vs AsyncTask


128

ฉันสับสนว่าเมื่อใดจะเลือก AsyncTask มากกว่าตัวจัดการ บอกว่าฉันมีรหัสฉันต้องการเรียกใช้ทุก n วินาทีซึ่งจะปรับปรุง UI ทำไมฉันถึงเลือกอันหนึ่งมากกว่าอีกอัน?


1
สิ่งนี้มีความซับซ้อนมากขึ้นด้วย AsyncTaskLoaders ดูstackoverflow.com/q/7120813/969325สำหรับข้อมูลเพิ่มเติม
Warpzit

คำตอบ:


75

IMO, AsyncTask ถูกเขียนขึ้นเพื่อให้วิธีที่สะดวกและง่ายต่อการใช้งานเพื่อให้การประมวลผลพื้นหลังในแอพ Android โดยไม่ต้องกังวลเกี่ยวกับรายละเอียดในระดับต่ำมากเกินไป (เธรดลูปข้อความ ฯลฯ ) มันมีวิธีการโทรกลับที่ช่วยในการกำหนดเวลางานและยังปรับปรุง UI ได้อย่างง่ายดายเมื่อจำเป็น

อย่างไรก็ตามมันเป็นสิ่งสำคัญที่จะต้องทราบว่าเมื่อใช้ AsyncTask นักพัฒนากำลังส่งข้อ จำกัด ของมันซึ่งเป็นผลมาจากการตัดสินใจออกแบบที่ผู้เขียนของชั้นใช้ ยกตัวอย่างเช่นเมื่อเร็ว ๆ นี้ฉันพบว่ามีการ จำกัด จำนวนงานที่สามารถกำหนดเวลาโดยใช้ AsyncTasks

ตัวจัดการมีความโปร่งใสของทั้งสองและอาจช่วยให้คุณมีอิสระมากขึ้น ดังนั้นหากคุณต้องการควบคุมสิ่งต่างๆมากขึ้นคุณจะต้องเลือก Handler ไม่เช่นนั้น AsynTask ก็ใช้ได้ดี


ถูกตัอง. ฉันใช้ AsyncTasks สำหรับการทำงานเบื้องหลังทั้งหมดในโครงการของฉัน เมื่อถึงจุดหนึ่งฉันเริ่มที่จะถึงขีด จำกัด งานสูงสุดดังนั้นงานของฉันจะเริ่มหลังจากเสร็จงานอื่นเท่านั้น ในที่สุดฉันต้องเปลี่ยนโครงสร้างทั้งหมดของฉันเพื่อหยุดใช้ asynctasks และหลีกเลี่ยงข้อ จำกัด นั้น
tbraun

5
จาก Honeycomb on AsyncTasksจะถูกรันบนเธรดเดียวดังนั้นจึงไม่มีการขนานกันอีกต่อไป คุณยังคงสามารถเรียกใช้พวกเขาในการExecutorดำเนินการparalel
MrSnowflake

63

กฎง่ายๆของฉันคือ:

  • ถ้าคุณกำลังทำบางสิ่งบางอย่างโดดเดี่ยวที่เกี่ยวข้องกับ UI AsyncTaskเช่นการดาวน์โหลดข้อมูลที่จะนำเสนอในรายการไปข้างหน้าและการใช้งาน

  • ถ้าคุณกำลังทำหลายงานซ้ำเช่นการดาวน์โหลดภาพหลายภาพที่จะแสดงในImageViews(เช่นการดาวน์โหลดภาพขนาดเล็ก) Handlerเมื่อดาวน์โหลดใช้งานกับคิว


ตัวจัดการอยู่ในระดับ API 1 และ ASYNCTASK ในระดับ API 3 มันจะถูกยกเลิกค่าใช้จ่ายใด ๆ ? เพราะกำลังให้ความสำคัญกับการย้ายแอพพลิเคชั่นจากเวอร์ชั่นที่เก่ากว่าไปที่ 2.2 & 2.3 ..
yokks

10
จะไม่มีการคัดค้านในเร็ว ๆ นี้ ตัวจัดการจะไม่ถูกคัดค้านเนื่องจาก UI ถูกสร้างขึ้นโดยรอบ
alexanderblom

คุณไม่ควรใช้ตัวโหลดเพื่อโหลดข้อมูลสำหรับ UI ของคุณที่จะนำเสนอ?
nbarraille

19

พยายามหลีกเลี่ยงการใช้ AsyncTask ทุกครั้งที่เป็นไปได้ด้วยเหตุผลดังต่อไปนี้:

  • AsyncTask ไม่รับประกันว่าจะเรียกใช้เนื่องจากมีฐาน ThreadPool และขนาดสูงสุดที่กำหนดโดยระบบและหากคุณสร้าง asynctask มากเกินไปในที่สุดพวกเขาก็จะถูกทำลายในที่สุด

  • AsyncTask สามารถยกเลิกได้โดยอัตโนมัติแม้ในขณะที่ใช้งานขึ้นอยู่กับวงจรชีวิตของกิจกรรมและคุณไม่สามารถควบคุมได้

  • วิธี AsyncTask ที่ทำงานบน UI Thread เช่น onPostExecute สามารถเรียกใช้งานได้เมื่อกิจกรรมที่อ้างถึงไม่ปรากฏให้เห็นอีกต่อไปหรืออาจอยู่ในสถานะเลย์เอาต์ต่าง ๆ เช่นหลังจากการวางแนว

สรุปได้ว่าคุณไม่ควรใช้วิธีเชื่อมโยง UIT ของ AsyncTask ซึ่งเป็นข้อได้เปรียบหลัก !!! นอกจากนี้คุณควรทำงานที่ไม่สำคัญกับ doInBackground เท่านั้น อ่านกระทู้นี้สำหรับข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับปัญหานี้:

AsyncTask มีข้อบกพร่องทางแนวคิดจริงๆหรือฉันแค่ทำบางสิ่งหายไป?

เพื่อสรุปพยายามที่จะชอบใช้ IntentServices, HandlerThread หรือ ThreadPoolExecutor แทน AsyncTask เมื่อปัญหาที่อ้างถึงข้างต้นเป็นปัญหาสำหรับคุณ แน่นอนว่ามันจะต้องใช้งานมากกว่านี้ แต่ใบสมัครของคุณจะปลอดภัยกว่า


ใช่ฉันใช้เวลาหลายครั้งเสียใจกับการใช้ AsyncTasks หลายครั้ง พวกเขาดูดี แต่ ... ปัญหามากมาย!
SMBiggs

6
ฉันขอโทษที่โพสต์คะแนนของคุณอย่างรุนแรง แต่ฉันไม่สามารถปล่อยให้เอฟเฟ็กต์สไตล์ที่ไม่ดีของคุณกับแอนดรอยด์ จุดหนึ่ง คุณไม่ควรมีหลายกระทู้ที่ทำงานอยู่ หากคุณเจอสิ่งนี้สถาปัตยกรรมของคุณก็จะเป็น foobar จุดที่ 2. ทำอย่างไรบนโลก .. โอเคใช่ทุกอย่างใน Android เป็นเกมฟรีสำหรับตัวเก็บขยะ ... คุณจะเห็นพฤติกรรมของผู้สังเกตการณ์ตามที่อธิบายไว้ข้างต้นในบางกรณีที่ไม่เหมาะสม จุดที่ 3 การจัดการงานของคุณไม่ใช่ทักษะที่หยาบคายเป็นทักษะสามเณร คุณจะฆ่ามันเมื่อคุณโทร onPause หรือถอดออกอย่างถูกต้องและแนบไปด้วย
StarWind0

1
vogella.com/tutorials/AndroidBackgroundProcessing/article.htmlนี่คือทั้งหมดที่คุณต้องเรียนรู้วิธีการทำงานอย่างถูกต้องโดยไม่มีปัญหาด้านบน (สมมติว่าคุณไม่ได้ทำอะไรคล้ายการพ่นงานสองสามร้อย)
StarWind0

16

หากคุณต้องการทำการคำนวณทุก ๆ x วินาทีคุณควรกำหนดตารางเวลาRunnableด้วยHandler(พร้อมpostDelayed()) และRunnableควรเริ่มต้นในเธรด UI ปัจจุบัน หากคุณต้องการเริ่มในเธรดอื่นให้ใช้ HandlerThread AsyncTask ใช้งานง่ายกว่าสำหรับเรา แต่ไม่ดีไปกว่าตัวจัดการ


7

ตัวจัดการเกี่ยวข้องกับเธรดหลักของแอปพลิเคชัน มันจัดการและกำหนดเวลาข้อความและ runnables ส่งจากกระทู้พื้นหลังเพื่อเธรดหลักของแอ

AsyncTask มีวิธีการง่าย ๆ ในการจัดการเธรดพื้นหลังเพื่ออัปเดต UI โดยไม่ต้องปิดกั้นโดยการใช้เวลานาน

คำตอบคือทั้งสองสามารถใช้เพื่ออัปเดต UI จากเธรดพื้นหลังความแตกต่างจะอยู่ในสถานการณ์จำลองการทำงานของคุณ คุณอาจพิจารณาใช้ตัวจัดการมันคุณต้องการโพสต์ข้อความล่าช้าหรือส่งข้อความไปยัง MessageQueue ในการสั่งซื้อเฉพาะ

คุณอาจพิจารณาใช้ AsyncTask หากคุณต้องการแลกเปลี่ยนพารามิเตอร์ (เช่นการอัปเดต UI) ระหว่างเธรดหลักของแอปและเธรดพื้นหลังอย่างง่ายดาย


3
คุณสามารถสร้างตัวจัดการของคุณเองที่เกี่ยวข้องกับหัวข้ออื่น
Aleksejs Mjaliks

ตัวจัดการไม่จำเป็นต้องเชื่อมโยงกับเธรดหลัก (เธรด UI) มันเชื่อมโยงกับเธรดที่มันถูกสร้างอินสแตนซ์และจัดการกับข้อความหรือเรียกใช้ของที่มาถึงคิวข้อความเธรดนี้ นอกจากนี้ยังสามารถส่งข้อความและวัตถุที่เรียกใช้ไปยังคิวข้อความเธรดนี้
azec-pdx

2

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

Handlerไม่เข้าใจอะไรเลยยกเว้นการจัดการ Runnables และข้อความ นอกจากนี้ก็สามารถทำงานได้หลายครั้งตามที่คุณต้องการ คุณมีอิสระในการตัดสินใจว่าจะต้องติดเธรดใดไว้อย่างไรมันสื่อสารกับตัวจัดการอื่น ๆHandlerThreadได้อย่างไร ดังนั้นจึงมีความยืดหยุ่นและเหมาะสำหรับงานซ้ำ ๆ

ตรวจสอบชนิดที่แตกต่างของHandlerตัวอย่างที่นี่


0

พวกเขาเป็นคำถามสัมภาษณ์ที่ดีที่สุดที่ถาม AsyncTask - พวกเขาจะใช้ในการ offload ของเธรด UI และทำงานในพื้นหลัง Handlers - Android dosent มีวิธีการสื่อสารโดยตรงระหว่าง UI และเธรดพื้นหลัง ตัวจัดการต้องใช้เพื่อส่งข้อความหรือเรียกใช้ผ่านคิวข้อความ

ดังนั้น AsyncTasks จึงถูกใช้เมื่อต้องการใช้งานในพื้นหลังและตัวจัดการใช้เพื่อการสื่อสารระหว่าง UI และเธรดพื้นหลัง


0

doInBackground - โดยทั่วไปแล้วจะทำงานในเธรดอื่น onPostExecute - โพสต์ผลลัพธ์บนเธรด UI และเป็นการส่งข้อความภายในไปยังตัวจัดการของเธรดหลัก เธรด UI หลักมีตัวเชื่อมโยงและตัวจัดการเกี่ยวข้องแล้ว

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

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