Back in lesson four we learned that the Android runtime
will kill apps with no visible activities
in order to free resources needed by the foreground app.
But what if your app has tasks that need to continue
when the activity isn't visible?
Things like downloading files, uploading photos, or playing music.
Well, there's an application component for that.
Services.
We've already introduced activities, content providers,
broadcast receivers and intents.
Services are the final piece to the Android app component puzzle.
You start services much like you do activities,
by passing in an intent to a startService call.
And you can stop services the same way.
By calling stopService and passing in the name
of the service you want to stop.
Unlike activities, services have no user interface
and they run at a higher priority than background activities.
This means that an app with a running service,
is less likely to be killed by the runtime
in order to free resources for the foreground activities.
In fact, by default, the system will attempt to restart services
that are terminated before they are stopped from within the app.
This is reflected in this simplified lifecycle.
Compared to activities, services are designed
to execute longer running tasks that shouldn't be interrupted.
Typically, you'll only need to override the onStartCommad handler,
which is where you begin the background task
you wish to execute.
But notice that there are no handlers for monitoring changes in state,
to reflect the app moving to the background.
This is because the running service itself,
sends a signal to the framework,
that the containing app should be considered higher priority
than other apps in the background that don't have running services.
In some cases your service may performing a task,
that while not having UI, can't be interrupted
without interfering with the user experience.
For example, playing music or helping with in car navigation.
In these cases you can indicate that your server
should be considered to be running in the foreground
by calling startForeground.
You'll notice that this call takes in a notification.
This will be displayed, and can't be dismissed
until the service has stopped or you call stopForeground.
You'll learn more about notifications a little later, with Dan.
But for now, note that a foreground service runs at the same priority
as a foreground activity.
Making it nearly impossible for the runtime to kill
in order to free resources.
Now you may be thinking to yourself, I could save a lot of trouble
dealing with lifecycles, just by creating long running
or even foreground services.
Well, I grew up along the coast in Australia,
so I learned young that swimming against the current
is exhausting and ultimately futile.
In this case, that means making it more difficult
for the system to manage resources,
ultimately leading to a worse user experience.
Swim with the current.
Use foreground services only when and for as long as
absolutely necessary.
And stop all service as as quickly as possible.
It's also important to note that like activities and receivers,
services run on the main thread.
So you'll need to use a background thread or think task
to execute the long running tasks you wish to do within your service.
To make life easier, you can use the intent service class.
Which implements the most common best practice pattern, for using intents,
which are executed within a service.
It creates a queue of incoming intents, passed in when start service is called.
These are then processed sequentially on a background thread,
within the onHandleIntent handler, within your intent service implementation.
When the queue is empty, the service self terminates
until a new intent is received, and the process begins again,
Services are a powerful tool and it's important to understand
how you can use them,
but in practice there's often a framework alternative
to rolling your own service implementation.
Whether that be an intent service for executing background tasks
or the sync adapter which you'll learn about later in this lesson.
Perfect for performing background data synchronization.
وبالرجوع إلى الدرس الرابع حيث تعلمنا أن وقت تشغيل Android سوف
يوقف التطبيقات دون وجود أنشطة مرئية
من أجل إطلاق .الموارد المطلوبة لتطبيقات الصدارة
ولكن ماذا إذا كان بالتطبيق الخاص بك مهام تتطلب المتابعة
عندما يكون النشاط مرئيًا؟
أشياء مثل تنزيل الملفات .أو تحميل الصور أو تشغيل الموسيقى
حسنًا، هناك مكون .تطبيق من أجل ذلك
.الخدمات
قدمنا أنشطة وموفري محتوى ومستقبلي
.بث وأهدافاً بالفعل
تعد الأنشطة جزءًا من لغز .مكون تطبيق Android
سوف تبدأ في الخدمات بنفس طريقة
أدائك للأنشطة .من خلال تمرير الأهداف من أجل طلب startService
كما يمكنك إيقاف الخدمات .بنفس الطريقة
وعبر طلب stopService ،وتمرير اسم الخدمة
سوف تتمكن .من الإيقاف
وعلى النقيض من الأنشطة، لا يوجد للخدمات واجهة مستخدم
وتعمل بأولوية .عالية على عكس أنشطة الخلفية
،يشير ذلك إلى أن التطبيق الذي يتميز بوجود خدمة تقل به احتمالية
الوقف عبر وقت التشغيل
من أجل إطلاق .الموارد المطلوبة لتطبيقات الصدارة
ففي حقيقة الأمر وعبر الوضع الافتراضي سوف يحاول النظام إعادة تشغيل الخدمات
التي تم .إنهاؤها قبل أن تتم عملية الإيقاف داخل التطبيق
يظهر ذلك في .دورة الحياة البسيطة
،مقارنة بالأنشطة فالخدمات معدة لتنفيذ
مهام التشغيل .الأطول التي لا يتعين أن تتوقف
وعلى نحو مماثل، سوف تحتاجون فقط إلى إلغاء
معالج onStartCommad وهو المكان الذي تبدأ منه المهمة في الخلفية والتي
.ترغبون في تنفيذها
لكنه يرجى ملاحظة عدم وجود معالجات من ،أجل مراقبة التغييرات على الحالة
من أجل إظهار التطبيق المنقول .إلى الخلفية
يتمثل السبب في ذلك في إرسال خدمات التشغيل
ذاتها لإشارة إلى إطار
العمل بأن التطبيق المدرج يتعين أن يوضع في الاعتبار كأولوية قصوى
على خلاف غيره من .التطبيقات في الخلفية والتي ليس لها خدمات عاملة
،وفي بعض الحالات قد تقوم خدماتكم بتنفيذ مهام
ليس لها واجهة مستخدم ويمكن إيقافها
دون تدخل مع .تجربة المستخدم
ومن الأمثلة على ذلك، تشغيل .الموسيقى أو المساعدة في التصفح داخل السيارة
وفي هذه الحالات، يمكنكم الإشارة إلى أن الخادم الخاص
بكم يتعين اعتبار تشغيله
.في الخلفية عبر طلب startForeground
سوف تلاحظ أن هذا الطلب مدرج .في الإشعار
سوف يظهر ذلك ولن يكون بالإمكان الرفض حتى
تتوقف الخدمة أو تطلب .stopForeground
سوف تتعلمون كثيرًا بشأن الإشعارات .في وقت لاحق مع Dan
لكنه في الوقت الحالي، يرجى ملاحظة أن خدمات الصدارة
.تجري بنفس أولوية أنشطة الصدارة
وهو ما يجعل الإيقاف من المستحيل تقريبًا بالنسبة لوقت التشغيل
.من أجل إطلاق الموارد
يمكنكم التفكير في أنفسكم في الوقت الحالي، حيث
يمكنني توفير الكثير من المتاعب في التعامل مع دورات الحياة
.وذلك فقط عبر إنشاء التشغيل لوقت طويل أو خدمات الصدارة
حسنًا، نشأت في منطقة ،الساحل الأسترالي
ولذلك تعلمت حين كنت صغيرًا أن السباحة ضد التيار ستكون
.مرهقة وغير مجدية في نهاية المطاف
وفي تلك الحالة، يشير ذلك إلى أن زيادة الصعوبة بالنسبة للنظام في
إدارة الموارد سوف
يؤدي في .نهاية المطاف إلى تجربة مستخدم سيئة
.اسبحوا مع التيار
استخدموا خدمات الصدارة فقط عند وخلال الضرورة
.الملحة
وأوقفوا كل الخدمات .على وجه السرعة
من الضروري أيضًا ملاحظة أنه مثل ،الأنشطة والمستقبلات
.تعمل الخدمات على السلسلة الرئيسية
ولذلك، سوف تحتاجون إلى استخدام ،سلسلة عمليات في الخلفية أو التفكير في المهمة
لتنفيذ مهام التشغيل الطويلة .التي ترغب في أدائها خلال خدماتك
ومن أجل تسهيل الأمور، يمكنكم استخدام .فئة خدمة معالجة الأهداف
وهي التي تنفذ أفضل أنماط الممارسة وأكثرها شيوعًا
.من أجل استخدام معالجة الأهداف التي يتم تنفيذها خلال الخدمة
يعمل ذلك على خلق قائمة انتظار للأهداف الواردة .والتي يتم تمريرها عند طلب خدمة البدء
تتم معالجة ذلك بشكل متسلسل في سلسلة عمليات
في الخلفية خلال معالجة onHandleIntent أثناء .تنفيذ خدمة معالجة الأهداف
،عندما تكون قائمة الانتظار فارغة تتوقف الخدمة
الذاتية إلى حين تلقي هدف
،جديد وتبدأ العملية مرة ثانية وتعد تلك الخدمات
أداة قوية وهامة
من أجل فهم كيف يمكنكم ،استخدامها
غير أنه يكون هناك إطار .بديل في الممارسة من أجل تشكيل تنفيذ الخدمات الخاصة بك
وسواءٌ أكان ذلك من خدمات معالجة الأهداف الخاصة
بتنفيذ مهام في الخلفية .أو محول المزامنة والذي سوف تتعلمون بشأنه لاحقًا في هذا الدرس
يُعد ممتازًا فيما يتعلق بمزامنة .بيانات الخلفية
La lección 4 nos enseñó que Android Runtime cerrará las apps
sin actividades visibles para poder liberar recursos
necesarios para la app en primer plano.
¿Pero qué pasa si tiene tareas que necesitan continuar
cuando la actividad no es visible? Por ejemplo, descargar archivos,
subir fotos, o reproducir música. Para eso, hay un componente de app.
Los servicios.
Ya presentamos actividades, proveedores de contenido,
receptores de notificaciones e intentos.
Los servicios son la última pieza del puzle de los componentes de aplicación.
Los servicios se inician igual que las actividades,
pasando Intent a una llamada startService.
Puedes detener servicios llamando a stopService
y pasando el nombre del servicio que quieres detener.
Los servicios no poseen interfaz como las actividades,
y se ejecutan con mayor prioridad que las actividades en segundo plano.
Así, es menos probable que una app con un servicio en ejecución
la termine el tiempo de ejecución para liberar recursos para el primer plano.
Es más, el sistema intentará reiniciar los servicios terminados
antes de que sean detenidos desde la propia app.
Esto se refleja en este ciclo de vida simplificado.
A diferencia de las actividades, los servicios están diseñados
para ejecutar tareas largas que no deben ser interrumpidas.
Suele bastar con sobrescribir el manejador onStartCommand,
que inicia la tarea en segundo plano que se quiere ejecutar.
Pero no hay manejadores para monitorear cambios de estado
que reflejen el paso de la app a segundo plano.
Se debe a que el servicio en ejecución manda una señal al marco
de que dé mayor prioridad a esta app
que a otras en segundo plano, que no tienen servicios en ejecución.
A veces, tu servicio realizará una tarea que, aunque no tenga interfaz,
no se puede interrumpir sin interferir con la experiencia del usuario.
Por ejemplo, reproducir música o indicar la ruta para el auto.
En estos casos, puedes indicar que el servicio ha de tomarse
como si se ejecutara en primer plano, llamando a startForeground.
Esta llamada incluye una notificación que será visible
y no puede ser descartada hasta que el servicio se detenga
o llames a stopForeground.
Más tarde aprenderás con Dan más sobre las notificaciones.
Ahora fíjate que un servicio en primer plano se ejecuta
con la misma prioridad que una actividad en primer plano,
por lo que el tiempo de ejecución no puede cerrarlas para liberar recursos.
Tal vez pienses que podrías ahorrarte muchos problemas con los ciclos
si creas servicios de larga duración o en primer plano.
Yo crecí en la costa de Australia,
y aprendí que nadar a contracorriente es agotador y a la larga inútil.
Me refiero a que dificultar la gestión de recursos al sistema
lleva a una peor experiencia de usuario.
Nada a favor de la corriente.
Usa servicios en primer plano cuando sea absolutamente necesario,
y detén todos los servicios lo más rápido posible.
Al igual que las actividades y receptores,
los servicios se ejecutan en el hilo principal.
Necesitarás usar un hilo en segundo plano o una tarea de respuesta
para ejecutar tareas de larga duración dentro de tu servicio.
Más fácil, utiliza la clase IntentService,
que implementa la mejor práctica a la hora de usar intentos o intents
que se ejecutan dentro de un servicio.
Crea una cola de intentos por venir, que se pasa al llamar a startService.
Luego se procesan de forma secuencial en un hilo de ejecución en segundo plano,
dentro del manejador onHandleIntent, dentro de IntentService.
Cuando la cola se vacía, el servicio se termina por sí solo
hasta que recibe un nuevo intento y el proceso comienza otra vez.
Los servicios son excelentes herramientas y es importante entender su uso,
pero en la práctica suele haber un marco alternativo
para implementar el servicio, ya sea IntentService,
para ejecutar tareas en segundo plano, o SyncAdapter,
que aprenderás más adelante en esta lección,
ideal para sincronizar datos en segundo plano.
Kembali ke Lesson 4
Android runtime akan mematikan apps
tanpa aktifitas yang terlihat untuk mengosongkan resources
yang dibutuhkan oleh foreground app.
Bagaimana bila app Anda memiliki task yang harus berjalan terus
saat aktifitas tersembunyi?
Seperti mengunduh file, mengunggah foto, atau memutar musik.
Ada komponen aplikasi untuk itu.
Services.
Kami sudah perkenalkan aktifitas, penyedia konten,
penerima broadcast dan intent.
Services adalah bagian terakhir dari teka-teki komponen app Android.
Anda memulai services sama seperti melakukan aktifitas,
dengan memasukkan intent ke panggilan startService.
Services dapat dihentikan dengan cara yang sama.
Memanggil stopService dan memasukkan nama service
yang ingin dihentikan.
Tak seperti aktifitas, services tidak memiliki interface pengguna
dan bekerja pada prioritas lebih tinggi dari aktifitas background.
Ini berarti app dengan service berjalan,
cenderung tidak dimatikan oleh runtime
untuk mengosongkan resource bagi aktifitas foreground.
Faktanya, secara default, sistem akan berusaha mengaktifkan kembali services
yang dimatikan sebelum dihentikan dari dalam app.
Ini tercermin dalam lifecycle sederhana.
Dibanding dengan aktifitas, services dirancang
untuk mengeksekusi task yang bekerja lebih lama hingga tidak boleh diganggu.
Biasanya, Anda hanya perlu override handler onStartCommand,
di sinilah tempat memulai background task
yang ingin Anda eksekusi.
Perhatikan tidak ada handler untuk memonitor perubahan status
untuk mencerminkan app yang pindah ke background.
Ini karena service yang berjalan mengirim sinyal ke framework,
bahwa app yang dimuatnya harus dianggap prioritas lebih tinggi
dibanding app lain di background yang tidak menjalankan services.
Pada satu waktu service Anda mungkin sedang melakukan task,
yang meski tidak memiliki UI, tak boleh diinterupsi
tanpa mengganggu kenyamanan pengguna.
Misalnya, memutar musik atau butuh bantuan navigasi mobil.
Dalam hal ini Anda dapat menunjukkan bahwa server Anda
harus dianggap sedang berjalan di foreground
dengan memanggil startForeground.
Anda perhatikan panggilan ini memunculkan notifikasi.
Yang akan ditampilkan, dan dapat diabaikan
sampai service berhenti atau Anda memanggil stopForeground.
Sesaat lagi Anda akan belajar lebih dalam tentang notifikasi, bersama Dan.
Sampai disini, ingatlah foreground service bekerja pada prioritas yang sama
seperti aktifitas foreground,
membuatnya hampir mustahil dimatikan runtime
untuk mengosongkan resources.
Mungkin Anda berpikir akan banyak masalah
dengan lifecycles, karena membuat services foreground
yang berjalan lama.
Begini, Aku besar di pesisir Australia,
mengerti sejak kecil bahwa berenang melawan arus
melelahkan dan sia-sia.
Itu berarti akan lebih sulit
bagi sistem untuk mengatur resources,
yang akhirnya memberi pengalaman tidak enak bagi pengguna.
Berenang mengikuti arus.
Gunakan foreground services hanya saat
dan selama dibutuhkan.
Matikan semua services secepat mungkin.
Penting juga diingat bahwa seperti aktifitas dan penerima,
services bekerja di thread utama.
Jadi Anda perlu memakai background thread atau async task
untuk mengeksekusi task panjang yang ingin dilakukan dalam services.
Untuk memudahkan, Anda dapat gunakan intent service class,
yang mengimplementasi pola terbaik dan paling lazim dilakukan
untuk penggunaan intent yang dieksekusi di dalam service.
Menghasilkan antrian intent, yang masuk saat start service dipanggil.
Semua ini lalu diproses berurutan di background thread,
di dalam handler onHandleIntent,
dalam implementasi intent service Anda.
Saat antrian kosong, service berhenti sendiri
hingga menerima intent baru, dan prosesnya dimulai lagi.
Services adalah tool yang luar biasa dan penting bagi Anda
memahami cara memakainya,
tapi pada prakteknya kadang ada alternatif framework
untuk menjalankan implementasi service Anda.
Apakah itu intent service untuk mengeksekusi background task
ataukah sync adapter yang akan Anda pelajari nanti.
Bagus untuk melakukan sinkronisasi data background.
レッスン4では
フォアグラウンドアプリが リソースを開放するために
見えるActivityがない時に Android Runtimeが アプリを終了することを学びました
しかしアプリに ファイルや写真のアップロードや 音楽の再生のような
Activityが見えない時にも継続する必要のある
タスクがある場合はどうでしょう？
そのためのアプリケーションコンポーネントが Serviceです
すでにActivity、コンテンツプロバイダ、
BroadcastReceiver、インテントを導入しました
ServiceはAndroidアプリケーション コンポーネントのパズルの最後のピースです
インテントをstartService呼び出しに渡すことで
ServiceをActivityと同じように開始します
また停止したいService名を stopService呼び出しに渡すことで
同様にServiceを止められます
ServiceにはUIがなく
バックグラウンドのActivityより 高い優先順位で実行されます
フォアグラウンドのActivityが使う リソースを開放するために
Service実行中のアプリが停止させられる 可能性が低いのです
実際にはデフォルトのシステムは
アプリ内からServiceを止める前に 終了させられたServiceを再開しようとし
この単純化されたライフサイクルに 反映されます
Activityと比べると Serviceは
中断すべきではない長時間のタスクを 実行するために設計されています
基本的には バックグラウンドタスクを始める onStartCommandハンドラを
オーバーライドする必要があるだけです
しかしアプリのバックグラウンドへの移動を 反映するような
状態の変化を監視するハンドラがない点に 注目してください
これは実行中のServiceが フレームワークへ次のように通知するからです
“このアプリはバックグラウンドにあり 実行中のServiceを持たない他のアプリより”
“優先度が高い”
Serviceはタスクを実行するかもしれません
このタスクはUIを持たないので 中断の際にユーザ体験を妨げてしまいます
例えば音楽の再生や カーナビのサポートなどです
こういった場合 startForeground 呼び出しによって
Serviceがフォアグラウンドで 実行されているとするべき と通知できます
またこの呼び出しが Notificationを含みます
これは画面に表示されて
Serviceが止まるかstopForegroundが 呼び出されるまで閉じません
あとでダンと一緒に Notificationについて学びます
しかし今は フォアグラウンドのServiceが
フォアグラウンドのActivityと同じ優先順位で 実行される点に注意してください
これでRuntimeがリソースを開放するために Serviceを停止することはほぼ不可能となります
皆さんも考えているかもしれませんが
長時間のServiceや フォアグラウンドのServiceを作成することで
ライフサイクルを扱う際のトラブルを かなり回避できます
私はオーストラリアの海岸沿いで育ったので
潮の流れに逆らうとひどく疲れて 結局無駄だということを子供の頃に学びました
この場合システムがリソースを管理して
最終的に価値のあるユーザ体験をもたらすのは
より困難になることを意味します 流れに身を任せましょう
フォアグラウンドのServiceは 絶対に必要な時にだけ使いましょう
またすべてのServiceを できるだけ速やかに止めましょう
ActivityやReceiverなどのように
Serviceもメインスレッドで 実行される点も重要です
Service内で長時間のタスクを実行するためには
バックグラウンドスレッドや AsyncTaskを使う必要があります
簡単にするために IntentServiceクラスが使えます
これはインテントを使うために Service内で実行される
最も一般的で最良のパターンを実装します
インテントのキューも作成し startServiceの呼び出しの時にこれを渡します
そしてキューはIntentServiceの実装にある onHandleIntentハンドラ内で
バックグラウンドスレッドで 連続して処理されます
キューが空の時 Serviceは新たなインテントを受信して
プロセスが再開するまでの間 自らを終了させます
Serviceは強力なツールなので 使い方を理解することは重要です
しかし実際には皆さんのServiceの実装に対する 代替的なフレームワークがあります
バックグラウンドタスクを実行するための IntentServiceか
このレッスンのあとの方で学ぶSyncAdapterです
これはバックグラウンドのデータ同期に最適です
4강에서 우리는 안드로이드 runtime이
눈에 띄는 활동이 없는 앱을 종료시킨다는 것을 배웠고
foreground 앱의 활동을 위한 것이라는 사실도 배웠죠
하지만 앱이 보이지 않는 곳에서도
처리해야 할 활동이 있다면
예를 들어 다운로드, 사진 업로드 음악 재생 같은 것이 있다면 어떨까요?
그런 것을 위한 앱 component가 있습니다 activity, content provider와
broadcase receiver, intent 같은 것들을 이미 모두 배웠죠
서비스는 안드로이드 앱 component를 위한
마지막 관문과도 같습니다
service call을 시작할 때와 마찬가지로
서비스를 시작할 수 있습니다
서비스를 종료하는 방법도 중지하고자 하는 서비스 이름의
stop service를 호출하여 똑같이 할 수 있습니다
activity와는 다르게 service는
UI가 없고 백그라운드 활동보다
우선순위도 높지 않습니다 실행중인 서비스를 가지고 있는 앱은
foreground 활동을 위한 리소스 확보 때문에 run time에 의해
종료될 가능성이 있다는 뜻입니다
하지만 기본 설정으로 시스템은 앱 내에서 중지된 서비스를
재시작하려 할 것입니다
이것은 이렇게 단순화된 life cycle에 의해서 된 것인데요
Activity와는 다르게 서비스는 방해 없이 오래 작동해야 하는
작동을 수행하도록 설계되었습니다 보통 실행하고 싶은 백그라운드 작업을
시작하려고 할 때만 onStartCommand handler를
override 하게 되는데요 앱 상태 변화를 모니터링하고
백그라운드 앱을 reflect할 handler가 없다는 것을 기억하세요
서비스 자체를 실행하는 것은
포함하는 앱은 서비스가 없는 백그라운드 앱보다
우선해야 한다는 신호를 보내주는데요
어떤 경우에는 서비스가 UI는 없지만
UI에 방해되어서는 안 되는 작업을
실행하고 있을 수도 있습니다
예를 들어 자동차 네비게이션을 수행하는 도중에
음악을 재생할 수도 있는데 그때 서버는
startForeground를 호출해서 foreground에서 돌아가고 있고
이런 호출은 notification을
필요로 한다는 걸 알 수 있죠
이것은 서비스가 중지되거나 stopForeground를 호출할 때까지
표시되거나 dismiss될 수도 있습니다 notification에 대해서는
조금 후에 Dan과 배울 겁니다 하지만 지금은 foreground 서비스가
foreground activity와 같은 우선순위로 실행된다는 것을
기억하세요, 그렇게 되면 run time이
리소스를 확보하기 위해 종료하는 것이 거의 불가능하죠
life cycle을 배우면 많은 문제를 피해갈 수 있고
long running이나 foreground서비스를 생성하는 것만 하면 된다고
생각하실지도 모르겠습니다만 저는 호주의 해안가에서 자랐는데
해류 반대방향으로 수영하는 것은
힘들기만 하고 쓸모없는 일이라는 걸 알고 있지요
이 경우에는 시스템이 리소스를 관리하는 걸
더 어렵게만 만들고 사용자 경험을 악화시킬 뿐입니다
해류와 같은 방향으로 수영하세요
foreground 서비스는 꼭 필요할 때만 사용하시고요
가능한 빨리 모든 서비스를 중지시키세요
activity와 receiver와 같이 서비스도
main thread에서 실행됩니다
그래서 서비스 내에서 long running task로
실행시키고자 하는 작업을 background thread로
처리할 수 있습니다 문제를 쉽게 만들기 위해
internet service class를 이용할 수 있습니다 그것은 제일 흔하고 좋은 practice패턴을
시행하는데요, 서비스 내에서 실행되는
intent를 이용합니다 들어오는 intent의 목록을 만들고
start service가 호출될 때 넘어 들어옵니다
그것들은 background thread에서 차례대로 처리되고
intent service implementation의 onHandleIntent handler안에서 처리되죠
목록이 비어있을 때 서비스 자체는 새로운 intent가
받아지고 프로세스가 시작할 때까지 종료됩니다
서비스는 강력한 툴입니다 사용하는 것을
배우는 것도 중요하지만 현실적으로 framework를 통해
자기만의 service implementation을
실행하는 방법도 종종 있습니다 백그라운드 작업을 실행할
intent service이든 싱크 어댑터든 간에 다음 시간에 배울 겁니다
백그라운드 데이터 싱크에 딱 맞는 것들이죠
Na lição quatro aprendemos que o tempo de execução do Android
descartará aplicativos sem atividades visíveis
a fim de liberar os recursos necessários pelo aplicativo em primeiro plano.
Mas, e se o aplicativo tiver tarefas que precisam prosseguir
quando a atividade não estiver visível?
Coisas como baixar arquivos, carregar fotos ou reproduzir música.
Bem, existe um componente de aplicativo para isso.
Serviços.
Já introduzimos atividades, provedores de conteúdo,
broadcast receivers e intenções.
Serviços são a peça final no quebra-cabeça de componentes do aplicativo do Android.
Você inicia serviços como inicia atividades,
passando uma intenção para uma chamada startService.
E você pode pará-los da mesma maneira.
Ao chamar stopService e passar o nome
do serviço que você quer parar.
Diferentemente de atividades, serviços não têm interface do usuário
e sua execução tem prioridade sobre as atividades de segundo plano.
Isso significa que um aplicativo com um serviço em execução,
tem menos probabilidade de ser descartado pelo tempo de execução
a fim de liberar recursos para as atividades de primeiro plano.
De fato, por padrão, o sistema tentará reiniciar os serviços
que são finalizados antes que eles sejam interrompidos dentro do aplicativo.
Isso se reflete neste ciclo de vida simplificado.
Em comparação com atividades, serviços são designados
para executar tarefas mais longas, que não devem ser interrompidas.
Geralmente, só é necessário substituir o manipulador onStartCommad,
que é onde começa a tarefa em segundo plano
que você quer executar.
Mas, observe que não há manipuladores para monitoramento de alterações no estado,
a fim de refletir a movimentação do aplicativo para o segundo plano.
Isso porque o próprio serviço de execução
envia um sinal para o framework,
de que o aplicativo contido deve ser considerado como de prioridade mais alta
do que outros aplicativos em segundo plano que não têm serviços em execução.
Em alguns casos, seu serviço pode estar executando uma tarefa,
que embora não tenha IU, não pode ser interrompida
sem interferir na experiência do usuário.
Por exemplo, reproduzir música ou ajudar em navegação de carro por GPs.
Nesses casos, você pode indicar que o servidor
deve ser considerado para execução em primeiro plano,
chamando startForeground.
Você perceberá que essa chamada recebe uma notificação.
Ela será exibida, e não poderá ser descartada
até que o serviço seja parado ou você chame stopForeground.
Você aprenderá mais sobre notificações um pouco mais adiante, com Dan.
Mas por agora, observe que um serviço em primeiro plano tem a mesma prioridade de execução
que uma atividade em primeiro plano.
Tornando-o quase impossível de ser descartado pelo tempo de execução
para liberar recursos.
Agora, você deve estar pensando, eu poderia evitar muito problemas
ao lidar com ciclos de vida, apenas criando serviços de longa execução
ou até mesmo em primeiro plano.
Bem, eu cresci na costa da Austrália,
e aprendi desde cedo que nadar contra a corrente
é desgastante e, em última análise, inútil.
Nesse caso, significa tornar mais difícil
para o sistema gerenciar recursos,
levando, enfim, a uma experiência de usuário pior.
Nade a favor da corrente.
Use serviços em primeiro plano somente quando e enquanto
absolutamente necessário.
E pare todo o serviço o mais rapidamente possível.
Também é importante observar que como atividades e receptores,
serviços são executados no thread principal.
Então, você terá de usar um thread em segundo plano ou pensar em uma tarefa
para executar tarefas de longa duração que deseja executar no serviço.
Para facilitar use a classe IntentService.
Que implementa o padrão mais comum de melhores práticas, para o uso de intenções,
que são executadas em um serviço.
Isso cria uma fila de intenções de entrada, que são passadas quando StartService é chamado.
Elas são, então, processadas sequencialmente em um thread em segundo plano,
no manipulador onHandleIntent, dentro da implementação do serviço de intenção.
Quando a fila fica vazia, o serviço se encerra
até que uma nova intenção seja recebida, e o processo recomeça.
Serviços são uma ferramenta poderosa e é importante entender
como você pode usá-los,
mas, na prática, sempre há um framework alternativo
para rodar sua própria implementação de serviço.
Seja um serviço de intenção para executar tarefas em segundo plano
ou o adaptador de sincronização do qual falaremos mais adiante nesta lição.
Perfeito para executar sincronização de dados em segundo plano.
В уроке номер четыре мы выяснили,
что Android полностью останавливает приложения без видимых активностей,
чтобы высвободить ресурсы, требуемые для приложения на переднем плане.
Но что, если у вашего приложения
есть задачи, которые должны продолжать выполняться,
когда приложение не видно?
Например, скачивание файлов, закачка в сеть фотографий
или проигрывание музыки.
Для этого есть специальный компонент: Services (Службы).
Мы уже познакомили вас с активностями, контент-провайдерами,
приёмниками передач и интентами.
Службы –- это последняя часть пазла среди компонентов приложения Android.
Службы запускают примерно так же, как и активности,
передачей интента вызову startService.
И останавливают их так же:
вызовом stopService с передачей ему названия службы,
которую надо остановить.
В отличие от активностей у компонента Службы
нет пользовательского интерфейса,
и приоритет у них выше, чем у фоновых активностей.
Это значит, что приложение с работающей службой
будет реже закрываться во время работы
с целью высвобождения ресурсов для приложения на переднем плане.
По умолчанию система будет даже пытаться перезапускать службы,
приостановленные до того,
как они были остановлены самим приложением.
Это изображено здесь в упрощённом жизненном цикле.
По сравнению с активностями
службы должны выполнять более длительные задачи,
которые нельзя прерывать.
Обычно достаточно переопределить обработчик onStartCommand.
Именно здесь вы начинаете фоновую задачу,
которую вам необходимо выполнить.
Но заметьте, что здесь нет обработчиков, отслеживающих изменение состояния,
когда приложение становится фоновым,
потому что работающая служба
сама посылает ядру сигнал,
что содержащему её приложению надо дать больший приоритет,
чем остальным фоновым приложениям без работающих служб.
В некоторых случаях служба может выполнять задачу,
не имеющую интерфейса, которую нельзя прервать так,
чтобы пользователь этого не заметил.
Например, проигрывание музыки или помощь в управлении машиной.
В таких случаях необходимо обозначить,
что службу надо рассматривать как работающую на переднем плане,
вызывая startForeground.
Заметьте, что метод требует уведомление в качестве аргумента.
Оно будет показано на экране и останется там,
пока служба не остановлена или не вызван stopForeground.
Дэн расскажет вам попозже подробнее об уведомлениях.
Пока заметьте, что активная служба имеет тот же приоритет,
что и активность переднего плана.
В результате её почти невозможно остановить полностью
с целью высвобождения ресурсов.
У вас могла появиться мысль:
многих проблем, связанных с жизненными циклами,
можно было бы избежать,
просто создавая длительные или даже активные службы.
Я вырос на побережье Австралии,
и рано понял, что плыть против течения утомительно
и, в конце концов, бесполезно.
В данном случае это усложнило бы управление ресурсами для системы
и в результате ухудшило бы работу системы для пользователя.
Плывите по течению.
Используйте активные службы только тогда,
когда это реально необходимо.
И останавливайте службы при первой же возможности.
Важно также заметить, что, как и активности с приёмниками,
службы работают в главном потоке.
Поэтому придётся использовать фоновый поток или асинхронную задачу,
чтобы выполнять длительные задачи внутри вашей службы.
Чтобы сделать жизнь легче, можно использовать класс IntentService,
который реализует самую распространённую и практичную схему
для использования интентов, исполняемых внутри службы.
Он создаёт очередь входящих интентов, передаваемых при вызове startService.
Затем они обрабатываются последовательно в фоновом потоке
внутри обработчика onHandleIntent внутри реализации вашей службы интента.
Когда очередь пуста, служба останавливается.
Когда приходит новый интент, процесс начинается снова.
Службы -- очень мощный инструмент.
Важно понять, как вы можете их использовать.
Но на практике часто лучше использовать готовое решение
вместо разработки собственной реализации службы,
будь то служба интентов для выполнения фоновых задач
или синхронный адаптер, о котором вы узнаете позже в этом уроке,
идеальный для выполнения фоновой синхронизации данных.
Quay lại bài 4 ta đã học được rằng Android runtime
sẽ kill các app mà không hiện activites nào
để giải phóng tài nguyên cần thiết bởi các app đang hiển thị.
Nhưng nếu app của bạn có các tasks mà nó cần tiếp tục
khi activity không hiển thị thì sao?
Ví du như downloading files, uploading photos, hay playing music.
Well, sẽ có một application component để làm điều đó.
Services.
Ta đã giới thiệu activities, content providers,
broadcast receivers và intents.
Services là mảnh ghép cuối cùng của bảng xếp hình Android app component.
Bạn start services cũng như khi bạn làm với activities,
bằng việc truyền trong một intent trong lệnh startService.
Và bạn có thể stop services bằng cách tương tự.
Bằng việc gọi stopService và truyền vào
tên của service bạn muốn dừng.
Không giống như activities, services không có giao diện người dùng
và nó chạy với mức ưu tiên cao hơn các background activities.
Điều này nghĩa là một app với một service đang chạy,
ít có khả năng bị killed bởi the runtime
để giải phóng tài nguyên cho các activities đang hiển thị.
Trên thực tế, mặc định, hệ thống sẽ cố restart services
mà bị chấm dứt trước khi nó bị dừng từ trong app.
Điều này được thể hiện trong lifecycle đơn giản này.
So với activities, services được thiết kế
để chạy các tác vụ lâu hơn mà không nên bị gián đoạn.
Thường thì, bạn chỉ cần override onStartCommand,
là nơi bạn bắt đầu tác vụ chạy nền
mà bạn muốn chạy.
Nhưng chú ý là không có handlers nào để theo dõi các thay đổi trong trạng thái,
để phản ánh app đang di chuyển tới background.
Điều này vì bản thân các dịch vụ đang chạy,
gửi một tín hiệu tới framework,
mà app đang chứa được cân nhắc là ưu tiên cao hơn
các apps khác trong background mà không có các running services.
Trong vài trường hợp, service của bạn có thể thực hiện một task
mà trong khi không có UI, không thể bị gián đoạn
mà không can thiệp vào trải nghiệm người dùng.
Ví dụ, chơi nhạc hay điều hướng xe hơi.
Trong các trường hợp này bạn có thể chỉ ra rằng services của bạn
nên chạy dưới nên
bằng việc gọi startForeground.
Bạn sẽ chú ý rằng lệnh này có chứa một notification.
nó sẽ được hiển thị và không thể bị bỏ qua
cho đến khi service dừng hoặc bạn gọi stopForeground.
Bạn sẽ học thêm về notifications sau đây, với Dan.
Nhưng giờ, chú ý rằng một foreground service chạy với mức ưu tiên
tương tự với một foreground activity.
Làm nó gần như không thể bị kill trong lúc chạy
để giải phóng bộ nhớ.
Giờ bạn có thể nghĩ về bản thân, tôi có thể thoát khỏi rất nhiều rắc rối
với lifecycles, chỉ việc tạo một service chạy lâu
hoặc thậm chí là foreground services.
Well, tôi lớn lên theo bờ biển ở Australia,
nên tôi đã học được rằng bơi ngược dòng
là rất mệt mỏi và vô ích.
Trong trường hợp này, nghĩa là càng làm cho hệ thống
khó quản lý tài nguyên hơn,
cuối cùng dẫn tới một trải nghiệm người dùng tồi tệ.
Hãy bơi theo dòng.
Dùng các foreground services chỉ khi nào và để làm gì
thực sự cần thiết.
Và dừng tất cả service nhanh nhất có thể.
Cũng quan trọng để chú ý rằng cũng như activities và recieivers,
services chạy trên Main thread.
Nên bạn sẽ không phải dùng một background thread asynctask
để chạy một tác vụ tốn thời gian bạn muốn làm trong service.
Để làm cuộc sống đơn giản hơn, bạn có thể dùng intent servicec class.
Nó có các bài luyện tập tốt nhất, để sử dụng intent
để được thực hiện trong một service.
Nó tạo một hàng đợi của các intents sắp tới, được truyền khi startService được gọi.
chúng nó sau đó được xử lý tuần tự trên background thread,
trong onHandleIntent handler trong intent service của bạn.
Khi hàng đợi rỗng, service sẽ tự chấm dứt
cho đến khi một intent mới được nhận, và process lại bắn đầu
Services là một công cụ mạnh mẽ và thật quan trọng để hiểu
bạn có thể sử dụng nó như nào,
nhưng trong thực tế có một nền tảng thay thế
để thực hiện service của bạn.
Dù nó là một intent service để chạy các background task
hay sync adapter mà bạn sẽ được học sau sau trong bài này,
tuyệt vời để thực hiện đồng bộ dữ liệu nền.
在第四课中 我们学习了 Android 运行时
会终止没有可见 activity 的应用
来释放资源以满足前台运行应用的需要
但如果应用需要在 activity 不可见时
继续运行任务该怎么办？
比如说下载文件、上传照片或播放音乐
有一个程序组件就可以专门解决此问题
那就是服务
我们已经介绍了 activity、内容提供器、
广播接收器和 intent
服务就是 Android 应用组件拼图中的最后一片
启动服务的方法与 activity 类似
就是将 intent 传递给 startService 调用
你也可以用同样的方式停止服务
只要调用 stopService 然后传入
你想要结束的服务名
与 activity 不同 服务没有用户界面
并且比后台 activity 的优先级更高
这就意味着正在运行服务的应用
不太可能因为要给前台运行的 activity
释放资源而被运行时终止
事实上 在默认情况下 系统会试图重启
那些在应用内暂停之前就被终止了的服务
这都反映在这个简化的生命周期图中
与 activity 相比 服务旨在用于
执行那些运行时间更长且不应被中断的任务
一般来说 你只需要重写 onStartCommad 处理程序
如此来开始你希望执行的
后台任务
不过要注意的是 没有能够用于监控状态变化的处理程序
以反映移到后台的应用
这是因为运行中的服务本身
会向框架发送信号
告诉它所包含的应用应该比没有
正在运行服务的其它后台应用的优先级更高
在某些情况下 你的服务可能在执行一项
没有 UI 的任务 无法在不干扰
用户体验的情况下被中断
比如说 播放音乐或使用车载导航
在这些案例中 你可以调用 startForeground
以此来表明你的服务
应该在前台运行
你会发现 这个调用收到一个通知
通知会显示出来 并且在服务停止或
在你调用 stopForeground 前 都无法被解除
大家稍后会与 Dan 一道学习更多有关通知的知识
但现在只要知道前台服务运行时的优先级
与前台 activity 的优先级相同即可
这样 运行时就难以终止应用
以释放资源了
你可能在想 如果我可以创建长时间运行的服务
甚至前台服务 就能避免
应用生命周期带来的许多麻烦
我在澳大利亚的海滨长大
在很小的时候就知道 逆着水流游泳会让你精疲力竭
甚至徒劳无功
在这个案例中 也就是说 如果这样做
会使系统难以管理资源
最后会导致获得很糟糕的用户体验
游泳时应该顺着水流
只有在绝对需要时
才使用前台服务
并且一但可能就尽快停止所有服务
另一个需要着重注意的地方就是与 activity 和接收器一样
服务是在主线程上运行的
所以 你需要使用后台线程或思考任务
来执行你想用服务完成的长时间运行任务
有一条捷径 你可以使用 intent 服务类
它可实施对使用 intent 来说最普遍的最佳方案模式
这是在服务之内执行的
它为传入的 intent 创建一个队列 调用 startService 时就把它们传进来
然后 这些 intent 就会按顺序在后台线程中
被 onHandleIntent 处理程序和 intent 服务实现程序处理掉
队列为空时 服务会自我终止
直到收到新的 intent 再开始处理
服务是一个强大的工具 学会如何使用
服务很重要
不过在实际运用中 通常有一个替代框架
来运行你自己的服务实现
可能是一个执行后台任务的 intent 服务
或是你在本课稍后会学到的同步适配器
它是执行后台数据同步的好帮手