اگر برنامهای اندروید ۱۵ یا بالاتر را هدف قرار دهد، سیستم محدودیتهایی را در مورد مدت زمان اجرای برخی سرویسهای پیشزمینه در حالی که برنامه شما در پسزمینه است، اعمال میکند. در حال حاضر، این محدودیت فقط برای سرویسهای پیشزمینه از dataSync و mediaProcessing اعمال میشود. محدودیتهای محدودکنندهتری برای نوع سرویس پیشزمینه shortService وجود دارد که در مستندات آن نوع سرویس مورد بحث قرار گرفته است.
رفتار تایم اوت
سیستم به سرویسهای پیشزمینه dataSync و mediaProcessing اجازه میدهد تا در مجموع ۶ ساعت در یک دوره ۲۴ ساعته اجرا شوند، پس از آن سیستم متد Service.onTimeout(int, int) سرویس در حال اجرا را فراخوانی میکند (که در اندروید ۱۵ معرفی شد). (نوع سرویس پیشزمینه mediaProcessing در اندروید ۱۵ اضافه شد.) محدودیت زمانی شش ساعته به طور جداگانه برای dataSync و سرویسهای mediaProcessing ردیابی میشود. به عنوان مثال، اگر یک سرویس dataSync فقط به مدت یک ساعت اجرا شود، برنامه فقط پنج ساعت برای سرویسهای پیشزمینه dataSync در دسترس خواهد بود، اما شش ساعت کامل برای سرویسهای mediaProcessing در دسترس خواهد بود.
وقتی یک سرویس پیشزمینه به محدودیت شش ساعته میرسد، سرویس چند ثانیه فرصت دارد تا Service.stopSelf() را فراخوانی کند. وقتی سیستم Service.onTimeout() را فراخوانی میکند، سرویس دیگر یک سرویس پیشزمینه محسوب نمیشود. اگر سرویس Service.stopSelf() را فراخوانی نکند، سیستم یک خطای داخلی ایجاد میکند. این خطا با پیام زیر در Logcat ثبت میشود:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"
برای جلوگیری از مشکلات ناشی از این تغییر رفتار، میتوانید یک یا چند مورد از موارد زیر را انجام دهید:
- از سرویس خود بخواهید که متد جدید
Service.onTimeout(int, int)را پیادهسازی کند. وقتی برنامه شما فراخوانی را دریافت کرد، مطمئن شوید کهstopSelf()را ظرف چند ثانیه فراخوانی میکنید. (اگر برنامه را فوراً متوقف نکنید، سیستم یک خطا ایجاد میکند.) - مطمئن شوید که سرویسهای
dataSyncوmediaProcessingبرنامهی شما در هر دورهی ۲۴ ساعته بیش از ۶ ساعت اجرا نمیشوند (مگر اینکه کاربر با برنامه تعامل داشته باشد و تایمر را مجدداً تنظیم کند). - سرویسهای پیشزمینهی
dataSyncیاmediaProcessingرا فقط در نتیجهی تعامل مستقیم کاربر شروع کنید؛ از آنجایی که برنامهی شما هنگام شروع سرویس در پیشزمینه است، سرویس شما شش ساعت کامل پس از رفتن برنامه به پسزمینه را در اختیار دارد. - به جای استفاده از این سرویسهای پیشزمینه، از یک API جایگزین مانند WorkManager استفاده کنید. به طور خاص، به جای استفاده از سرویس پیشزمینه
dataSync، استفاده از یک API جایگزین را در نظر بگیرید.
اگر سرویسهای پیشزمینه dataSync برنامه شما در ۲۴ ساعت گذشته به مدت ۶ ساعت اجرا شدهاند، نمیتوانید سرویس پیشزمینه dataSync دیگری را شروع کنید ، مگر اینکه کاربر برنامه شما را به پیشزمینه آورده باشد (که تایمر را ریست میکند). اگر سعی کنید سرویس پیشزمینه dataSync دیگری را شروع کنید، سیستم خطای ForegroundServiceStartNotAllowedException را با پیام خطایی مانند "محدودیت زمانی قبلاً برای نوع سرویس پیشزمینه dataSync تمام شده است" (Time limit already exhausted for forground service type dataSync) ارسال میکند.
آزمایش
برای آزمایش رفتار برنامه خود، میتوانید زمانهای همگامسازی دادهها را حتی اگر برنامه شما اندروید ۱۵ را هدف قرار نمیدهد (تا زمانی که برنامه روی یک دستگاه اندروید ۱۵ اجرا میشود) فعال کنید. برای فعال کردن زمانهای انتظار، دستور adb زیر را اجرا کنید:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
همچنین میتوانید دوره زمانی وقفه را تنظیم کنید تا آزمایش رفتار برنامهتان هنگام رسیدن به حد مجاز آسانتر شود. برای تنظیم یک دوره زمانی وقفه جدید برای سرویسهای پیشزمینه dataSync ، دستور adb زیر را اجرا کنید:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
برای تنظیم یک دوره زمانی جدید برای سرویسهای پیشزمینه mediaProcessing ، این دستور را اجرا کنید:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds