详解Android中Service组件(一)

拼搏现实的明天。 2022-08-10 03:49 290阅读 0赞

Service是Android四大组件之一。

  1. Android提供service类来专门创建处理长生命周期的应用程序组件以及不需要用户界面的功能。
  2. Android赋予service比处于非活动状态的Activity更高的优先级。和Activity BroadcastReceiver一样,运行在主线程
  1. Service主要用于执行Intent查找 处理数据 更新ContentProvider 激活Intent以及触发Notication等。

  2. Service的优先级比较高,通常情况下不会自动停止,因此自终止可以显著的改善应用程序中的资源占用情况。

  3. 有两种方式可以启动Service,分别为startService和bindService

下面先分别描述一下两种方式的异同及各自的生命周期。

A、startService

  1. 1.启动和停止方式:
  2. <span style="white-space:pre"> </span>//显示启动停止service
  3. Intent startServiceIntent = new Intent(this, MyService.class);
  4. startService(startServiceIntent);
  5. stopService(startServiceIntent);
  6. <span style="white-space:pre"> </span>//隐士启动停止service
  7. startServiceIntent = new Intent(MyService.START_SERVICE_ACTION);
  8. startService(startServiceIntent);
  9. stopService(startServiceIntent);
  10. <span style="white-space:pre"> </span>//service 自杀<pre name="code" class="java"><span style="white-space:pre"> </span>stopSelr();
  11. 2.生命周期:
  12. <span style="white-space:pre"> </span>11-09 11:43:45.243 23785-23785/com.happy.test.service I/MyService: ---onCreate---
  13. <span style="white-space:pre"> </span>11-09 11:43:45.243 23785-23785/com.happy.test.service I/MyService: ---onStartCommand---
  14. <span style="white-space:pre"> </span>11-09 11:43:45.243 23785-23785/com.happy.test.service I/MyService: ---onStart---
  15. <span style="white-space:pre"> </span>11-09 11:44:12.043 23785-23785/com.happy.test.service I/MyService: ---onStartCommand---
  16. <span style="white-space:pre"> </span>11-09 11:44:12.043 23785-23785/com.happy.test.service I/MyService: ---onStart---
  17. <span style="white-space:pre"> </span>11-09 11:44:15.233 23785-23785/com.happy.test.service I/MyService: ---onDestroy---
  18. onCreateService只会调用一次,如果启动后再次调用startService,会走onStartCommandonStart方法.
  19. 3.简述onStartonStartCommand的区别:
  20. /**
  21. * 废弃,被onStartCommand取代
  22. *
  23. * @param intent
  24. * @param startId
  25. */
  26. @Override
  27. public void onStart(Intent intent, int startId) {
  28. super.onStart(intent, startId);
  29. Log.i(TAG, "---onStart---");
  30. }
  31. /**
  32. * 1.android 2.0 API以后引入,提供了和onStart一样的功能,并且还允许你告诉系统,如果系统在显示调用stopService或stopSelf之前终止了service,那么应该如何启动service。
  33. * 2.实现service的标准模式是从此方法中创建和运行一个新线程,用来在后台执行处理,并在该线程完成后终止这个service
  34. *
  35. * @param intent
  36. * @param flags
  37. * @param startId
  38. * @return
  39. */
  40. @Override
  41. public int onStartCommand(Intent intent, int flags, int startId) {
  42. Log.i(TAG, "---onStartCommand---");
  43. return Service.START_STICKY;
  44. }
  45. 4.优缺点:

优:一旦开启,除非我们显示的调用stopService和stopSelf,正常情况下是不会停止的,会一直在后台运行

缺:虽然在Activity中开启的,但是activity缺无法调用service中的方法

B、bindService

  1. 1.简介:
  2. 要让一个Service支持绑定,需要实现onBind方法,并返回当前被绑定service的实例
  3. ServiceActivity绑定,后者拥有对前者的实例实例引用,可以对service中的方法进行调用
  4. Service与其它组件的连接表示为一个ServiceConnection,通过重写onServiceConnectedonServiceDisconnected获得对service的引用
  5. 2.生命周期:
  6. 11-09 16:48:02.310 12231-12231/com.happy.test.service I/MyService: ---onCreate---
  7. 11-09 16:48:02.310 12231-12231/com.happy.test.service I/MyService: ---onBind---
  8. 11-09 16:48:03.130 12231-12231/com.happy.test.service I/MyService: ---onUnbind---
  9. 11-09 16:48:03.130 12231-12231/com.happy.test.service I/MyService: ---onDestroy---
  10. 3.允许serviceactivity绑定,这样能够获得更加详细的接口。要让一个service支持绑定,需要实现onBind方法,并返回被绑定service的当前实例。

service代码:

  1. @Override
  2. public IBinder onBind(Intent intent) {
  3. Log.i(TAG, "---onBind---");
  4. return myBind;
  5. }
  6. private MyBind myBind = new MyBind();
  7. public class MyBind extends Binder {
  8. public MyService getService() {
  9. return MyService.this;
  10. }
  11. }
  12. @Override
  13. public boolean onUnbind(Intent intent) {
  14. Log.i(TAG, "---onUnbind---");
  15. return super.onUnbind(intent);
  16. }

Activity代码

  1. private ServiceConnection serviceConnection = new ServiceConnection() {
  2. @Override
  3. public void onServiceConnected(ComponentName name, IBinder service) {
  4. //当建立连接时调用
  5. mService = ((MyService.MyBind) service).getService();
  6. }
  7. @Override
  8. public void onServiceDisconnected(ComponentName name) {
  9. // 当service意外断开时接收
  10. mService = null;
  11. }
  12. };
  13. 4.下面就可以在activity中调用service中的方法了
  14. case R.id.bindService:
  15. bindService(startServiceIntent,serviceConnection, Context.BIND_AUTO_CREATE);
  16. break;
  17. case R.id.unbindService:
  18. unbindService(serviceConnection);
  19. break;
  20. case R.id.playMusic:
  21. mService.playMusic("月亮之上");
  22. break;
  23. case R.id.stopMusic:
  24. mService.stopMusic("月亮之上");
  25. break;
  26. 5.特点

该Service与Activity不同生,但共死,也就是说只要bindService后,该activity finish的时候,即使不显示的调用unBindService,系统也会帮我们完成此操作。

C、两种方式相结合

  1. 当我们既想让service长期在后台运行,又想让我们的activity可以调用service的方法的时候,可以才取这两种方式相结合的形势。具体流程为:
  2. startService-->bindService,这样即使我们activity finish掉,只会调用serviceonUnbind方法,而我们的service会继续在后台运行。这个时候,想停止service只能通过stopService或者stopSelf来实现了。

D、创建前台service

  1. service需要和用户直接交互的情况下,防止在内存不足时被kill掉,最合适的方法是把service的优先级提高到和前台activity一样高,可以通过调用servicestartForeground的方法实现。
  2. 比如,在播放音乐的过程中,前台service会直接和用户进行交互,因此可以调用startForeground方法,在调用此方法时还需要传入一个持续工作的notification,只要service在前台运行,这个notification就会显示。
  3. /**
  4. * 不完整代码,尤其是notification
  5. */
  6. public void startPlayBack() {
  7. // 当通知栏被点击时打开的activity
  8. Intent intent = new Intent(this, MainActivity.class);
  9. PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, 0);
  10. //设置notification
  11. Notification notification = new Notification();
  12. //设置notification持续展示
  13. notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
  14. startForeground(0, notification);
  15. }
  16. 如果有这样多个同时运行在前台并且不可停止的service,系统可能会变的比较卡顿。理想情况下,应该为用户提供一种禁用前台service的方法,比如当用户点击通知栏的时候,启动一个activity,调用stopForeground(true)来把service移到后台,并且可以决定是否移除通知栏。

发表评论

表情:
评论列表 (有 0 条评论,290人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Android详解—TextView

    这篇博文献给正在android学习路上的弟弟,希望有一天以下内容对你有所帮助。 了解一个类,首先要了解他的结构,尤其是API中的这种类。 先了解下`TextView`的结构