Asynctask و DesjectedExecutionexception وحد المهمة
-
21-09-2019 - |
سؤال
أنا أحضر الكثير من الصور المصغرة من خادم بعيد وعرضها في طريقة عرض شبكة ، باستخدام Asynctask. المشكلة هي أن عرض الشبكات الخاص بي يعرض 20 صورة مصغرة في وقت واحد ، بحيث ينشئ 20 من المعايير غير المتزامنة ويبدأ 20 ينفذ ، واحد لكل صورة مصغرة.
انا حصلت RejectedExecution
استثناء في الكود الخاص بي. أتذكر أنني قرأت في مكان ما أن هناك حدًا لعدد المهام التي يمكن أن تتمتع بها Asynctask في قائمة الانتظار في وقت واحد ، فقد أضرب ذلك. هل تم رفع هذا الشريط؟
هل هناك طريقة لزيادة هذا الحد؟ هل من الآمن تجاهل هذا الاستثناء فقط؟ (من خلال وجود فارغ catch(RejectedException e){}
منع؟)
أقوم بتشغيل هذا الرمز على محاكي Android 1.6 ومستوى API في الكود الخاص بي (minsdkversion هو 3). [تحرير: تمت إضافة معلومات مستوى SDK و API
المحلول
أتذكر أنني قرأت في مكان ما أن هناك حدًا لعدد المهام التي يمكن أن تتمتع بها Asynctask في قائمة الانتظار في وقت واحد ، فقد أضرب ذلك. هل تم رفع هذا الشريط؟
AsyncTask
يبدو أنه يدعم حاليًا 10 مؤشرات ترابط وعمق قائمة انتظار العمل 10. من الناحية النظرية ، من شأنه أن يدعم 20 عنصرًا ... إذا لم يكن هناك شيء آخر يستخدم AsyncTask
.
هل هناك طريقة لزيادة هذا الحد؟
احصل على الكود المصدري ، وقم بتعديله ، ووضعه في الحزمة الخاصة بك ، واستخدم ذلك. فعلت هذا مع بلدي AsyncTaskEx
, ، على الرغم من أن هذا يعتمد على مصدر Android 1.5.
هل من الآمن تجاهل هذا الاستثناء فقط؟
لن يتم طابور عملك للتنفيذ. ما إذا كان هذا "آمن" متروك لك. لست على علم بأي تأثيرات أخرى على AsyncTask
البنية الاساسية.
نصائح أخرى
لقد فعلت هذا الشيء نفسه بالضبط بنفسي في التطبيق.
لا يبدو تشغيل 20 مؤشر ترابط متوازي مرة واحدة لتنزيل الصور المصغرة من خادم ودفعها إلى محول البيانات فكرة جيدة بالنسبة لي. كل هذه المواضيع ستستقل فقط في جميع أنحاء بعضها البعض وتجول في طريق بعضها البعض.
بدلاً من ذلك ، سأطلق موضوعًا واحدًا فقط ، واطلب من ذلك جمع الصور المصغرة في حلقة ، وأضفها إلى المحول عند وصولها.
يمكنك استخدام المنفذ التسلسلي مع asynctask.executeOnexecutor ، لتسلسل مهامك ، ولكن هذا سيحد من المهمة إلى مهمة واحدة متزامنة فقط في ذلك الوقت. قد تكون جيدة على الرغم من الحصول على الصورة المصغرة:
myasynctask.executeOnexecutor (myasynctask.serial_executor ، [params]) ؛
المشكلة هي أن عدد ريثما المخالفات المتزامنة ل AsyncTask.THREAD_POOL_EXECUTOR
IS 128. بمجرد ملء قائمة الانتظار ، لا يمكن قائمة المخالفات الجديدة.
من رمز المصدر Asynctask:
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
في رأيي أن الحد لا معنى له على الإطلاق و AsyncTask.SERIAL_EXECUTOR
لديه قائمة انتظار غير محدودة.
"آمن" للتجاهل - تحتاج إلى التأكد من أن أي نوع من الإخطار الذي كنت تخطط للقيام به في مرحلة ما بعد التنفيذ سيتم القيام به هنا عندما تصطدم بالخطأ - وإلا فقد تترك شيئًا معلقًا إذا كان الرمز الآخر يجعل افتراضات حول الاستماع من هذه المهمة.