Service是android四大组件之一,没有用户界面,一直在后台运行。

为什么使用Service启动新线程执行耗时任务,而不直接在Activity中启动一个子线程处理?

1、Activity会被用户退出,Activity所在的进程就变成了空进程(没有任何活动组件的进程),系统需要内存可能会优先终止该进程;

2、如果宿主进程被终止,那么该进程内所有的子线程也会被终止,这样可能导致子线程无法执行完成;

3、其实两种方式都是可以处理耗时任务的,使用场景不同而已。

一、通过Start方式启动Service

这种方式启动的Sevice,访问者与service之间没有关联,即使访问者退出Service仍然执行

生命周期:onCreate()->onStartCommand()->onDestroy()

》定义一个继承Service的子类

  1. public class NormalService extends Service {
  2.  
  3. @Override
  4. public IBinder onBind(Intent arg0) {
  5. return null;
  6. }
  7.  
  8. @Override
  9. public int onStartCommand(Intent intent, int flags, int startId) {
  10. Toast.makeText(this, "启动成功", Toast.LENGTH_SHORT).show();
  11. Log.d("NormalService", "启动成功");
  12. //一般在这里启动新线程执行耗时的操作
  13. return super.onStartCommand(intent, flags, startId);
  14. }
  15. }

》在AndroidManifest.xml文件中配置该Service

  1. <service android:name="com.android.servicetest.service.NormalService" />

》在activity中使用

  1. private void startNormal() {
  2. nomalIntent = new Intent();
  3. nomalIntent.setClass(this, NormalService.class);
  4. startService(nomalIntent);
  5. }

二、通过bind方式启动Service

这种方式启动的Sercice,访问者与Service绑定在一起,访问者退出,Service也就终止了

生命周期:onCreate()->onBind()->onUnbind()->onDestroy()

》定义一个继承Service的子类

  1. public class BinderService extends Service {
  2.  
  3. private int count;
  4. private MyBinder mBinder;
  5.  
  6. @Override
  7. public IBinder onBind(Intent arg0) {
  8. if (mBinder == null) {
  9. mBinder = new MyBinder();
  10. }
  11. Toast.makeText(this, "绑定成功", Toast.LENGTH_SHORT).show();
  12. Log.d("BinderService", "绑定成功");
  13. return mBinder;
  14. }
  15.  
  16. @Override
  17. public void onCreate() {
  18. super.onCreate();
  19. new Thread(new Runnable() {
  20.  
  21. @Override
  22. public void run() {
  23. while (true) {
  24. try {
  25. Thread.sleep(1000);
  26. count++;
  27. } catch (Exception e) {
  28.  
  29. }
  30. }
  31. }
  32. }).start();
  33. }
  34.  
  35. public class MyBinder extends Binder {
  36. public int getCount() {
  37. return count;
  38. }
  39. }
  40. }

》在AndroidManifest.xml文件中配置该Service

  1. <service android:name="com.android.servicetest.service.BinderService" />

》在activity中使用

  1. private MyBinder mBinder;
  2.  
  3. private ServiceConnection conn = new ServiceConnection() {
  4.  
  5. @Override
  6. public void onServiceDisconnected(ComponentName arg0) {
  7.  
  8. }
  9.  
  10. @Override
  11. public void onServiceConnected(ComponentName arg0, IBinder binder) {
  12. mBinder = (BinderService.MyBinder) binder;
  13. }
  14. };
  15.  
  16. private void bindService() {
  17. bindIntent = new Intent();
  18. bindIntent.setClass(this, BinderService.class);
  19. bindService(bindIntent, conn, Service.BIND_AUTO_CREATE);
  20. }
  1. @Override
  2. protected void onDestroy() {
  3. super.onDestroy();
  4. unbindService(conn);
  5. }

Binder对象相当于Service组件的内部钩子,关联到绑定的Service组件;

当其他的程序组件绑定该Service时,Service会把Binder对象返回给其他程序组件,其他程序组件通过该Binder对象即可与Service组件进行实时通信。

三、IntentService,处理异步请求的服务

IntentService是Service的子类,它增加了额外的功能:

使用队列来管理请求Intent,每当客户端代码通过Intent请求启动IntentService时,IntentService会将该Intent加入队列中,然后开启一条新的worker线程处理队列中的Intent,因此不会阻塞主线程。

IntentService会按次序处理队列中的Intent,该线程保证同一时刻只处理一个Intent。

》IntentService的实现

  1. public class IntentServiceTest extends IntentService{
  2.  
  3. public IntentServiceTest() {
  4. super("IntentService");
  5. }
  6.  
  7. @Override
  8. protected void onHandleIntent(Intent arg0) {
  9. Toast.makeText(this, "启动成功", Toast.LENGTH_SHORT).show();
  10. Log.d("IntentServiceTest", "启动成功");
  11. //该方法可以执行耗时的操作
  12. long endTime = System.currentTimeMillis() + 20 * 1000;
  13. while(System.currentTimeMillis() < endTime){
  14. synchronized (this) {
  15. try{
  16. wait(endTime - System.currentTimeMillis());
  17. }catch(Exception e){
  18.  
  19. }
  20. }
  21. }
  22. }
  23. }

》在AndroidManifest.xml文件中配置该Service

  1. <service android:name="com.android.servicetest.service.IntentServiceTest" />

》在activity中使用

  1. private void startIntentService(){
  2. serviceIntent = new Intent();
  3. serviceIntent.setClass(this, IntentServiceTest.class);
  4. startService(serviceIntent);
  5. }

四、跨进程调用Service(AIDL Service)

Android各应用程序都运行在自己的进程中,进程之间无法直接进行数据交换,为了事项这种跨进程通信,Android提供了AIDL Service。

》创建AIDL文件,定义接口的源代码必须以.aidl结尾

  1. package com.android.servicetest.service;
  2.  
  3. interface IMusic{
  4. String getName();
  5. String getYear();
  6. }

定义好AIDL接口之后,ADT工具会自动在gen/com/android/servicetest/service/目录生成一个IMusic接口;

在该接口里包含一个Stub内部类,该内部类除了实现IMusic接口还实现了IBinder接口,这个Stub类将会作为远程Service的回调类。

》定义一个Service实现类

  1. public class MusicService extends Service{
  2.  
  3. private MusicBinder mBinder;
  4.  
  5. @Override
  6. public IBinder onBind(Intent arg0) {
  7. if(mBinder == null){
  8. mBinder = new MusicBinder();
  9. }
  10. Toast.makeText(this, "绑定成功", Toast.LENGTH_SHORT).show();
  11. Log.d("MusicService", "绑定成功");
  12. return mBinder;
  13. }
  14.  
  15. public class MusicBinder extends IMusic.Stub{
  16.  
  17. @Override
  18. public String getName() throws RemoteException {
  19. return "本草纲目";
  20. }
  21.  
  22. @Override
  23. public String getYear() throws RemoteException {
  24. return "2006";
  25. }
  26.  
  27. }
  28. }

》在AndroidManifest.xml文件中配置该Service

  1. <service android:name="com.android.servicetest.service.MusicService" />

》在activity中使用

  1. private IMusic musicService;
  2.  
  3. private ServiceConnection = new ServiceConnection() {
  4.  
  5. @Override
  6. public void onServiceDisconnected(ComponentName arg0) {
  7.  
  8. }
  9.  
  10. @Override
  11. public void onServiceConnected(ComponentName arg0, IBinder binder) {
  12. //获取远程Service的OnBind方法返回的对象的代理
  13. musicService = IMusic.Stub.asInterface(binder);
  14. }
  15. };
  16.  
  17. private void bindAidlService(){
  18. aidlIntent = new Intent();
  19. aidlIntent.setClass(this, MusicService.class);
  20. bindService(aidlIntent, connAidl, Service.BIND_AUTO_CREATE);
  21. }
  22.  
  23. private void showContent() {
  24. String content = "";
  25. try {
  26. content = musicService.getYear() + musicService.getName();
  27. } catch (Exception e) {
  28. }
  29. Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
  30. }
  1. @Override
  2. protected void onDestroy() {
  3. super.onDestroy();
  4. unbindService(connAidl);
  5. }

这种方式和绑定本地Service的差别很小,只是获取Service回调的方式有区别:

绑定本地Service时可以直接获取OnBind方法的返回值;绑定远程Service时获取的事OnBind方法返回的对象的代理。

Android服务(Service)研究的更多相关文章

  1. Android服务Service具体解释(作用,生命周期,AIDL)系列文章-为什么须要服务呢?

    Android服务Service具体解释(作用,生命周期,AIDL) 近期沉迷于上班,没有时间写博客了.解衣入睡,未眠.随起床写一篇博客压压惊! ##我们android系统为什么须要服务Service ...

  2. Android服务Service总结

    转自 http://blog.csdn.net/liuhe688/article/details/6874378 富貴必從勤苦得,男兒須讀五車書.唐.杜甫<柏學士茅屋> 作为程序员的我们, ...

  3. android服务Service(上)- IntentService

    Android学习笔记(五一):服务Service(上)- IntentService 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服 ...

  4. Android服务——Service

    服务 Service 是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件.服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行. 此外,组件可以绑定到服务,以与之进行 ...

  5. Android服务Service

    安卓Service服务 一    Service简介 Service是运行在后台的,没有界面的,用来处理耗时比较长的.Service不是一个单独的进程,也不是一个单独的线程. Service有两种类型 ...

  6. android 服务service开启和关闭

    startService()方法开启一个服务. 服务只会开启一次,如果服务已经创建,并且没有销毁,多次调用startService方法只会执行onStartCommand方法和onStart方法. 服 ...

  7. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

  8. Android服务之Service(其一)

    android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你 ...

  9. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

随机推荐

  1. 在Activity之间传递参数(三)——serializable和parcelable的区别

    传递值对象: 一.serializable实现:简单易用 serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可.Serializable 接口是一种 ...

  2. Linux下的Apache和PHP安全设置,如何开启PHP的安全模式

    Linux下的Apache和PHP安全设置 PHP安全模式开启,PHP5.3将不再有安全模式. (1) safe_mode:以安全模式运行php; 在php.ini文件中使用如下 safe_mode ...

  3. sql语句修改列

    1.修改列名的常用语句 exec sp_rename '[dbo].[Table_1].[birthday]','birth'  --将表中列名为birthday改为birdh 属性不变,用的是数据库 ...

  4. setTimeout和setInterval的注意事项

    精准问题 setTimeout的问题在于它并不是精准的,例如使用setTimeout设定一个任务在10ms后执行,但是在9ms后,有一个任务占用了5ms的cpu时间片,再次轮到定时器执行时,时间已经过 ...

  5. html5新增标签及兼容

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. PHP程序员进阶学习书籍参考指南

    PHP程序员进阶学习书籍参考指南 @heiyeluren lastmodify: 2016/2/18     [初阶](基础知识及入门)   01. <PHP与MySQL程序设计(第4版)> ...

  7. 【sublime xftp插件】 Host key verification failed ,错误处理

    错误背景: 1.CentOS7上面作为运行环境,Coding在本机的windows环境 2.在windows上安装sublime 3,然后保存代码通过xftp保存到centos7虚机上面. 3.Cen ...

  8. javascript的几种继承

    1.原型链继承:构造函数.原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.确认原型和实例之间的关系用instanceof. ...

  9. node在centos下的安装

    CentOS 下安装 Node.js 1.下载源码,你需要在https://nodejs.org/en/download/下载最新的Nodejs版本,本文以v4.6.2为例: cd /usr/loca ...

  10. Ubuntu菜鸟入门(二)—— apt认知,且完善语言安装包

    一  语言安装包安装 1  原因 虽然安装的中文版,但是由于安装包很小,所以汉化的不够完全,所以要安装后,再下载语言包进行安装 2  方法 二  apt--软件包管理器 1   软件源 (1) 介绍 ...