成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android Service學習之本地服務

移動開發 Android
Service是在一段不定的時間運行在后臺,不和用戶交互應用組件。讓我們通過這一篇文章來認識一下Android系統中的服務。

Service是在一段不定的時間運行在后臺,不和用戶交互應用組件。每個Service必須在manifest中 通過來聲明。可以通過contect.startservice和contect.bindserverice來啟動。

Service和其他的應用組件一樣,運行在進程的主線程中。這就是說如果service需要很多耗時或者阻塞的操作,需要在其子線程中實現。

service的兩種模式(startService()/bindService()不是完全分離的):

  • 本地服務 Local Service 用于應用程序內部。

    它可以啟動并運行,直至有人停止了它或它自己停止。在這種方式下,它以調用Context.startService()啟動,而以調用 Context.stopService()結束。它可以調用Service.stopSelf() 或 Service.stopSelfResult()來自己停止。不論調用了多少次startService()方法,你只需要調用一次 stopService()來停止服務。

    用于實現應用程序自己的一些耗時任務,比如查詢升級信息,并不占用應用程序比如Activity所屬線程,而是單開線程后臺執行,這樣用戶體驗比較好。

  • 遠程服務 Remote Service 用于android系統內部的應用程序之間。

    它可以通過自己定義并暴露出來的接口進行程序操作。客戶端建立一個到服務對象的連接,并通過那個連接來調用服務。連接以調用 Context.bindService()方法建立,以調用 Context.unbindService()關閉。多個客戶端可以綁定至同一個服務。如果服務此時還沒有加載,bindService()會先加載 它。

    可被其他應用程序復用,比如天氣預報服務,其他應用程序不需要再寫這樣的服務,調用已有的即可。

生命周期

Service的生命周期并不像Activity那么復雜,它只繼承了onCreate(),onStart(),onDestroy()三個方法,當我 們第一次啟動Service時,先后調用了onCreate(),onStart()這兩個方法,當停止Service時,則執行onDestroy() 方法,這里需要注意的是,如果Service已經啟動了,當我們再次啟動Service時,不會在執行onCreate()方法,而是直接執行 onStart()方法。

而啟動service,根據onStartCommand的返回值不同,有兩個附加的模式:

1. START_STICKY 用于顯示啟動和停止service。

2. START_NOT_STICKY或START_REDELIVER_INTENT用于有命令需要處理時才運行的模式。

服務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啟動服務。這兩個方法都可以啟動Service,但是它們的使用場合有所不同。

1. 使用startService()方法啟用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。

如果打算采用Context.startService()方法啟動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接著調用onStart()方法。

如果調用startService()方法前服務已經被創建,多次調用startService()方法并不會導致多次創建服務,但會導致多次調用onStart()方法。

采用startService()方法啟動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。

2. 使用bindService()方法啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。

onBind()只有采用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,多次調用Context.bindService()方法并不會導致該方法被多次調用。

采用Context.bindService()方法啟動服務時只能調用onUnbind()方法解除調用者與服務解除,服務結束時會調用onDestroy()方法。

看看官方給出的比較流程示意圖:

两种比较

官方文檔告訴我們,一個service可以同時start并且bind,在這樣的情況,系統會一直保持service的運行狀態如果service已經 start了或者BIND_AUTO_CREATE標志被設置。如果沒有一個條件滿足,那么系統將會調用onDestory方法來終止service.所 有的清理工作(終止線程,反注冊接收器)都在onDestory中完成。

擁有service的進程具有較高的優先級

官方文檔告訴我們,Android系統會盡量保持擁有service的進程運行,只要在該service已經被啟動(start)或者客戶端連接(bindService)到它。當內存不足時,需要保持,擁有service的進程具有較高的優先級。

1. 如果service正在調用onCreate,onStartCommand或者onDestory方法,那么用于當前service的進程則變為前臺進程以避免被killed。

2. 如果當前service已經被啟動(start),擁有它的進程則比那些用戶可見的進程優先級低一些,但是比那些不可見的進程更重要,這就意味著service一般不會被killed.

3. 如果客戶端已經連接到service (bindService),那么擁有Service的進程則擁有最高的優先級,可以認為service是可見的。

4. 如果service可以使用startForeground(int, Notification)方法來將service設置為前臺狀態,那么系統就認為是對用戶可見的,并不會在內存不足時killed。

如果有其他的應用組件作為Service,Activity等運行在相同的進程中,那么將會增加該進程的重要性。

本地service

1.不需和Activity交互的本地服務

  1. public class LocalService extends Service {
  2. private static final String TAG = "LocalService";
  3. @Override
  4. public IBinder onBind(Intent intent) {
  5. Log.i(TAG, "onBind");
  6. return null;
  7. }
  8. @Override
  9. public void onCreate() {
  10. Log.i(TAG, "onCreate");
  11. super.onCreate();
  12. }
  13. @Override
  14. public void onDestroy() {
  15. Log.i(TAG, "onDestroy");
  16. super.onDestroy();
  17. }
  18. @Override
  19. public void onStart(Intent intent, int startId) {
  20. Log.i(TAG, "onStart");
  21. super.onStart(intent, startId);
  22. }
  23. }
  24. Activity:
  25. public class ServiceActivity extends Activity {
  26. @Override
  27. protected void onCreate(Bundle savedInstanceState) {
  28. super.onCreate(savedInstanceState);
  29. setContentView(R.layout.servicedemo);
  30. ((Button) findViewById(R.id.startLocalService)).setOnClickListener(
  31. new View.OnClickListener(){
  32. @Override
  33. public void onClick(View view) {
  34. // TODO Auto-generated method stub
  35. startService(new Intent("com.demo.SERVICE_DEMO"));
  36. }
  37. });
  38. ((Button) findViewById(R.id.stopLocalService)).setOnClickListener(
  39. new View.OnClickListener(){
  40. @Override
  41. public void onClick(View view) {
  42. // TODO Auto-generated method stub
  43. stopService(new Intent("com.demo.SERVICE_DEMO"));
  44. }
  45. });
  46. }
  47. }

在AndroidManifest.xml添加:

  1. < service android:name =".LocalService" >
  2. < intent-filter >
  3. < action android:name ="com.demo.SERVICE_DEMO" />
  4. < category android:name ="android.intent.category.default" />
  5. intent-filter >
  6. service >

否則啟動服務時會提示new Intent找不到"com.demo.SERVICE_DEMO"。

對于這類不需和Activity交互的本地服務,是使用startService/stopService的最好例子。

運行時可以發現第一次startService時,會調用onCreate和onStart,在沒有stopService前,無論點擊多少次 startService,都只會調用onStart。而stopService時調用onDestroy。再次點擊stopService,會發現不會 進入service的生命周期的,即不會再調用onCreate,onStart和onDestroy。

而onBind在startService/stopService中沒有調用。

2.本地服務和Activity交互

對于這種case,官方的sample(APIDemo\app.LocalService)是最好的例子:

  1. /**
  2. * This is an example of implementing an application service that runs locally
  3. * in the same process as the application. The {@link LocalServiceController}
  4. * and {@link LocalServiceBinding} classes show how to interact with the
  5. * service.
  6. *
  7. *

    Notice the use of the {@link NotificationManager} when interesting things

  8. * happen in the service. This is generally how background services should
  9. * interact with the user, rather than doing something more disruptive such as
  10. * calling startActivity().
  11. */
  12. public class LocalService extends Service {
  13. private NotificationManager mNM;
  14. /**
  15. * Class for clients to access. Because we know this service always
  16. * runs in the same process as its clients, we don't need to deal with
  17. * IPC.
  18. */
  19. public class LocalBinder extends Binder {
  20. LocalService getService() {
  21. return LocalService.this;
  22. }
  23. }
  24. @Override
  25. public void onCreate() {
  26. mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
  27. // Display a notification about us starting. We put an icon in the status bar.
  28. showNotification();
  29. }
  30. @Override
  31. public int onStartCommand(Intent intent, int flags, int startId) {
  32. Log.i( "LocalService", "Received start id " + startId + ": " + intent);
  33. // We want this service to continue running until it is explicitly
  34. // stopped, so return sticky.
  35. return START_STICKY;
  36. }
  37. @Override
  38. public void onDestroy() {
  39. // Cancel the persistent notification.
  40. mNM.cancel(R.string.local_service_started);
  41. // Tell the user we stopped.
  42. Toast.makeText( this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
  43. }
  44. @Override
  45. public IBinder onBind(Intent intent) {
  46. return mBinder;
  47. }
  48. // This is the object that receives interactions from clients. See
  49. // RemoteService for a more complete example.
  50. private final IBinder mBinder = new LocalBinder();
  51. /**
  52. * Show a notification while this service is running.
  53. */
  54. private void showNotification() {
  55. // In this sample, we'll use the same text for the ticker and the expanded notification
  56. CharSequence text = getText(R.string.local_service_started);
  57. // Set the icon, scrolling text and timestamp
  58. Notification notification = new Notification(R.drawable.stat_sample, text,
  59. System.currentTimeMillis());
  60. // The PendingIntent to launch our activity if the user selects this notification
  61. PendingIntent contentIntent = PendingIntent.getActivity( this, 0,
  62. new Intent( this, LocalServiceController. class), 0);
  63. // Set the info for the views that show in the notification panel.
  64. notification.setLatestEventInfo( this, getText(R.string.local_service_label),
  65. text, contentIntent);
  66. // Send the notification.
  67. // We use a layout id because it is a unique number. We use it later to cancel.
  68. mNM.notify(R.string.local_service_started, notification);
  69. }
  70. }

這里可以發現onBind需要返回一個IBinder對象。也就是說和上一例子LocalService不同的是,

1. 添加了一個public內部類繼承Binder,并添加getService方法來返回當前的Service對象;

2. 新建一個IBinder對象——new那個Binder內部類;

3. onBind方法返還那個IBinder對象。

  1. /**
  2. *

    Example of binding and unbinding to the {@link LocalService}.

  3. * This demonstrates the implementation of a service which the client will
  4. * bind to, receiving an object through which it can communicate with the service.

  5. */
  6. public class LocalServiceBinding extends Activity {
  7. private boolean mIsBound;
  8. private LocalService mBoundService;
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.local_service_binding);
  13. // Watch for button clicks.
  14. Button button = (Button)findViewById(R.id.bind);
  15. button.setOnClickListener(mBindListener);
  16. button = (Button)findViewById(R.id.unbind);
  17. button.setOnClickListener(mUnbindListener);
  18. }
  19. private ServiceConnection mConnection = new ServiceConnection() {
  20. public void onServiceConnected(ComponentName className, IBinder service) {
  21. // This is called when the connection with the service has been
  22. // established, giving us the service object we can use to
  23. // interact with the service. Because we have bound to a explicit
  24. // service that we know is running in our own process, we can
  25. // cast its IBinder to a concrete class and directly access it.
  26. mBoundService = ((LocalService.LocalBinder)service).getService();
  27. // Tell the user about this for our demo.
  28. Toast.makeText(LocalServiceBinding. this, R.string.local_service_connected,
  29. Toast.LENGTH_SHORT).show();
  30. }
  31. public void onServiceDisconnected(ComponentName className) {
  32. // This is called when the connection with the service has been
  33. // unexpectedly disconnected -- that is, its process crashed.
  34. // Because it is running in our same process, we should never
  35. // see this happen.
  36. mBoundService = null;
  37. Toast.makeText(LocalServiceBinding. this, R.string.local_service_disconnected,
  38. Toast.LENGTH_SHORT).show();
  39. }
  40. };
  41. private OnClickListener mBindListener = new OnClickListener() {
  42. public void onClick(View v) {
  43. // Establish a connection with the service. We use an explicit
  44. // class name because we want a specific service implementation that
  45. // we know will be running in our own process (and thus won't be
  46. // supporting component replacement by other applications).
  47. bindService( new Intent(LocalServiceBinding. this,
  48. LocalService. class), mConnection, Context.BIND_AUTO_CREATE);
  49. mIsBound = true;
  50. }
  51. };
  52. private OnClickListener mUnbindListener = new OnClickListener() {
  53. public void onClick(View v) {
  54. if (mIsBound) {
  55. // Detach our existing connection.
  56. unbindService( mConnection);
  57. mIsBound = false;
  58. }
  59. }
  60. };
  61. }

明顯看出這里面添加了一個名為ServiceConnection類,并實現了onServiceConnected(從IBinder獲取Service對象)和onServiceDisconnected(set Service to null)。

而bindService和unbindService方法都是操作這個ServiceConnection對象的。

AndroidManifest.xml里添加:

  1. < service android:name =".app.LocalService" />
  2. < activity android:name =".app.LocalServiceBinding" android:label ="@string/activity_local_service_binding" >
  3. < intent-filter >
  4. < action android:name ="android.intent.action.MAIN" />
  5. < category android:name ="android.intent.category.SAMPLE_CODE" />
  6. intent-filter >
  7. activity >

這里沒什么特別的,因為service沒有需要什么特別的action,所以只是聲明service而已,而activity和普通的沒差別。

運行時,發現調用次序是這樣的:

bindService:

1.LocalService : onCreate

2.LocalService : onBind

3.Activity: onServiceConnected

unbindService: 只是調用onDestroy

可見,onStart是不會被調用的,而onServiceDisconnected沒有調用的原因在上面代碼的注釋有說明。

介紹onStartCommand()需要用到的幾個常量 (引自官方文檔)

START_NOT_STICKY

If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.

START_STICKY

If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand() with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as do wnloading a file.

Running a Service in the Foreground

具體內容查看官方文檔,主要是使用 startForeground() 和 stopForeground()方法。

責任編輯:徐川 來源: OSChina
相關推薦

2017-01-01 09:43:40

2025-02-13 08:30:11

2011-02-25 10:03:06

Proftpd

2010-09-30 09:42:06

2022-04-11 06:56:14

數據庫安全數據泄露

2011-03-03 17:01:17

Vsftpd

2018-04-20 07:52:23

2010-08-05 11:25:52

Windows Ser遷移

2012-12-27 10:30:46

Android開發Service后臺服務

2010-02-06 09:32:18

Android Ser

2023-08-03 08:36:30

Service服務架構

2021-09-09 15:07:36

鴻蒙HarmonyOS應用

2009-12-18 09:53:20

Android

2021-05-27 10:36:41

網絡通信內核

2011-06-01 10:58:54

Android Service

2014-09-16 11:17:36

AndroidService交互方式

2016-07-13 14:32:36

云計算

2021-12-11 22:21:00

服務配置文件

2023-10-12 00:07:27

Service單體微服務

2018-03-02 16:27:33

IOT語義互操作性本體論
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人久久久 | 久久久久久久久久久久一区二区 | www国产精 | 亚洲人成人一区二区在线观看 | 久久精品欧美一区二区三区不卡 | 国产高清在线 | 国产精品久久久久无码av | 欧美黄在线观看 | 99在线观看视频 | 亚洲一区二区三区免费观看 | 免费黄色av | 九九99九九精彩46 | 精品国产一区二区三区久久久蜜月 | 草草视频在线播放 | 亚洲欧美视频 | 欧美一级大片免费看 | 欧美一区二区三区视频在线播放 | 午夜寂寞福利视频 | 国产成人免费在线观看 | 中文字幕乱码一区二区三区 | 久草青青 | 一区二区三区观看视频 | 在线电影日韩 | 视频在线一区二区 | 中文字幕 在线观看 | 亚洲精品在线免费观看视频 | 国产综合久久久久久鬼色 | 四虎成人免费电影 | 久草视频在线看 | 久草网视频| 成人av一区| 成人精品国产一区二区4080 | 国产ts人妖另类 | 国产精品久久在线 | 国产精品精品 | 久久成人一区 | 欧美午夜激情在线 | 亚洲一区二区免费视频 | 久久久久久久国产 | 夜夜夜久久 | 最近免费日本视频在线 |