安卓基础知识(一) 服务(Service)

一.基本概念:

1.服务就是长期于后台运行的程序,可以理解为是一个,用于执行长期任务,并且与用户没有交互的组件。每一个服务需要在配置文件AndroidManifest.xml文件里面进行生命。使用的标签之后,和活动以及广播接收者的生命类似。

2.我们为什么要使用服务?
做一些需要长期执行的后台工作。

3.进程的优先级:
前台进程 > 可见进程 > 服务进程 > 后台进程 > 空进程

二.在活动中调用服务的方法

在主活动中调用服务内部的方法

错误实例思路是,先实例化一个服务的对象。再通过这个实例化的对象去调用服务中的方法。但是这样操作会出现空指针的异常。
MainActivity:
public void callServiceMethod(View view){Log.d(TAG, "callServiceMethod: ");FirstService firstService=new FirstService();firstService.sayhello();}
FirstService:public void sayhello(){Toast.makeText(this,"hello",Toast.LENGTH_SHORT).show();}
/*service继承自ContextWrapper,ContextWrapper继承自Context,就是说service就是继承了context。
报错会说context为空,因为context是由框架给我们的,由系统去调用起来,然后给它一个上下文(就是全局的一个环境的一个对象)。我们这样写相当于自己去创建和调用,应该让系统去创建和调用。直接在主方法中实例化Service再调用服务中的方法,会在造成空指针的异常报错
*/

在最开始实现服务时会强制我们实现onBind()方法也就是绑定方法,就是借助这个方法实现服务内部方法的调用。

在这里要先明确一下服务的两种启动方法:

1.bind服务

2.start服务

用第二种方法时startService开始服务,stopService终止服务。下面示例是用bind服务的方式启动服务。

   @Overridepublic IBinder onBind(Intent intent){Log.d(TAG, "onBind: 服务");return new InnerBinder();}

在onBind()中让我们返回一个IBinder。本来是返回一个null的,为了实现和Activity的交互,这里我们改写一下,让它返会一个InnerBinder()对象。

我们先创建一个叫做InnerBinder的内部类,我们让这个内部类去暴漏我们想让MainActivity实现的方法callServiceInnerMethod(),在callServiceInnerMethod()里面直接实现sayhello()。

下面是InnerBinder的一个继承关系层级。Binder里面会实现IBinder的接口,而我们继承了Binder,就不用再去实现这个接口了。

InnerBinder中的代码示例:

public class InnerBinder extends Binder{public void callServiceInnerMethod(){sayhello();}}

这里我们把sayhello()改成private不让服务外部调用。

 private void sayhello(){Toast.makeText(this,"hello",Toast.LENGTH_SHORT).show();}

紧接着,我们修改onBind()方法,让它直接返回一个InnerBinder对象就可以了。

@Override
public IBinder onBind(Intent intent){Log.d(TAG, "onBind: 服务");return new InnerBinder();}

之后我们在主活动中去实现绑定服务和解绑服务的方法就可以实现由这个活动去调用服务中的方法啦。需要注意的是bindService()这个方法里面需要写进去三个参数(intent,mConnection,创建的模式)。BIND_AUTO_CREATE的意思是,如果绑定的时候没有创建就新创建一个,如果已经创建,就只执行绑定。mConnection是我们需要重写的一个回调。这个bindService会有返回值,为了提高代码的可靠性,我们要用返回值来判断它是不是正确。ctrl+alt+f 可以把一个变量改为全局变量。

第二个参数的官方解释:
Receives information as the service is started and stopped.This must be a valid ServiceConnection object;it must not be null.

在服务启动和停止时接收信息。这必须是一个有效的 ServiceConnection 对象;它不能为空。就是说我们要将ServiceConnection()这个抽象方法实例化,然后传入bindService()中去。下面是在活动中调用服务方法的代码示例:

/*** 绑定服务* @param view*/public void bandServiceClick(View view){Intent intent=new Intent();intent.setClass(this, FirstService.class);isService = bindService(intent,mConnection,BIND_AUTO_CREATE);}private ServiceConnection mConnection=new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//连接上之后的回调Log.d(TAG, "onServiceConnected: 连接上之后的回调");mRemoteBinder = (FirstService.InnerBinder) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.d(TAG, "onServiceConnected: 没有连接上之后的回调");mRemoteBinder=null;//解开就null,释放资源}};/*** 解绑服务* @param view*/public void unbandServiceClick(View view){if (mConnection!=null&&isService){unbindService(mConnection);}}

ctrl+h看实现的接口,下面加深一下对两种启动模式不同点的理解。

三.服务的生命周期

通过这个图可以看到,两种启动Service的方式以及他们的生命周期,bindService的不同之处在于当绑定的组件销毁后,对应的Service也就被kill了。我们在使用onBind()启动模式时,需要在destory()中解绑,要不然退出程序会有内存泄漏。Service的声明周期相比与Activity的简单了许多,只要好好理解两种启动service方式的异同就行。

总结:

  1. bindService启动的服务在调用者和服务之间是典型的client-server的接口,即调用者是客户端,service是服务端,service就一个,但是连接绑定到service上面的客户端client可以是一个或多个。

  2. startService启动的服务默认无限期执行(可以通过Context的stopService或Service的stopSelf方法停止运行),bindService启动的服务的生命周期与其绑定的client息息相关。当client销毁的时候,client会自动与Service解除绑定,client也可以通过明确调用Context的unbindService方法与Service解除绑定。当没有任何client与Service绑定的时候,Service会自行销毁(通过startService启动的除外)。

  3. startService和bindService二者执行的回调方法不同:startService启动的服务会涉及Service的的onStartCommand回调方法,而通过bindService启动的服务会涉及Service的onBind、onUnbind等回调方法。

四.onBind()的大致流程

调用了bindService之后,由于Service此时还不存在,那么Android就会首先创建一个Service的实例,并执行其onCreate回调方法,onCreate方法在其生命周期中只会被调用一次。

然后会调用Service的onBind方法,该方法只有在第一次bindService调用后才会执行,onBind执行后会返回一个IBinder类型的实例,此时Android会将该IBinder实例存起来,这个IBinder实例是对所有client共享的。当下次其他的client执行bindService的时候,不会再执行onBind方法,因为我们之前已经得到了一个IBinder实例,Android会直接使用这个IBinder实例。

在得到了IBinder实例之后,Android会执行client端ServiceConnection中的onServiceConnected方法,在该方法中我们会得到IBinder实例,并通过该IBinder实例得到了TestService实例,这样我们的客户端ActivityA就通过IBinder与TestService建立了连接,我们就可以调用Service的一些方法。

五.接口的作用

用一个public的接口,在InnerBinder中实现这个接口。就是在服务中实现了接口的方法。而这个InnerBinder就相当于它父类的子类,当返回到产生联系的活动时,就拿到了InnerBinder实例对象。

private class InnerBinder extends Binder implements ICommunication {@Overridepublic void callServiceInnerMethod() {sayhello();//这个类此时是私有的,外面看不到}}@Overridepublic IBinder onBind(Intent intent){Log.d(TAG, "onBind: 服务");return new InnerBinder();}

此时,在调用时,我们不再把它强转为InnerBinder,而是强转为ICommunication接口类,因为ICommunication是公开的,而我们在服务端已经重写了callServiceInnerMethod() 方法,相当于通过接口的方式,间接的调用了服务中私有的一些方法。

下面是接口的实现

public interface ICommunication {void callServiceInnerMethod();
}

安卓基础知识(一) 服务(Service)相关推荐

  1. 安卓手机来电防火墙_安卓基础知识自动化测试

    安卓基础知识 本章重点探讨AndroidUI自动化测试过程中所涉及到的原理和技术.掌握这些知识是为学习Appium自动化测试框架打下基础. 学习目标 了解API和安卓版本的关系 了解安卓组件,安卓程序 ...

  2. 安卓基础知识之Activity篇(一):Activity生命周期

    安卓基础知识系列旨在简明扼要地提供面试或工作中常用的基础知识,让对安卓还不太熟悉的小伙伴更快地入门.同时自己在工作中,也没法完全记住所有的基础细节,写这样的系列文章,可以让自己形成一个更完备的知识体系 ...

  3. 信息化基础知识、服务管理、监理知识

    信息系统项目管理师备考,信息化基础知识.服务管理.监理知识易错点,常考点.

  4. 安卓基础知识-layout布局详解。

    安卓基础知识 1. 目录结构: src存放java源代码. gen存放系统自动生成的配置文件 res存放应用用到的所有资源文件,如图片,布局等等 drawable存放不同分辨率的图片 layout存放 ...

  5. 安卓基础知识之View篇(四):View 事件滑动冲突解决方案

    安卓基础知识系列旨在简明扼要地提供面试或工作中常用的基础知识,让对安卓还不太熟悉的小伙伴更快地入门.同时自己在工作中,也没法完全记住所有的基础细节,写这样的系列文章,可以让自己形成一个更完备的知识体系 ...

  6. FTP基础知识_FTP服务端应用开发

    网络编程_进阶_FTP服务器开发 文件传输是日常生活,工作中需求量较高的一项功能,FTP可以使用户在两个已联网的计算机之间传输文件,它是互联网环境下传递文件最主要的方法. 要了解FTP的传输过程,学习 ...

  7. Android允许后台活动管理,安卓基础知识(活动)

    一.四大组件 Android系统四大组件分别是活动(Activity).服务(Service).广播接收器(Broadcast Receiver)和内容提供器(Content Provider).其中 ...

  8. 信息系统项目管理笔记1-信息化基础知识、服务管理、监理知识

    信息化基础知识 特性:临时性.独特性.渐进明细性 5大过程组:启动.规划.执行.监控.收尾 9大管理:整体.范围.时间.成本.质量.人力资源.沟通.风险.采购----高项的说法 10大领域:范围.进度 ...

  9. 虹科分享 | CANopen协议基础知识——LSS服务

    CANopen是一种架构在CAN串行总线系统上的高层通讯协议,常被用于嵌入式系统与工业控制领域,包括电机控制.机器人制造.医疗.汽车等多个行业领域.本篇文章将主要介绍CANopen的LSS服务. 一. ...

最新文章

  1. IDEA真牛逼,900行又臭又长的类重构,几分钟搞定
  2. 石大ACM2587解题报告
  3. iOS 9音频应用播放音频之iOS 9音频播放进度
  4. python【蓝桥杯vip练习题库】ADV-290成绩排序
  5. 深圳网络推广总结影响网站优化的不友好设计有哪些?
  6. ITK:复制复合变换CompositeTransform
  7. Java重写、super关键字、继承中的构造方法
  8. kubernetes之一步一个坑
  9. C语言开发笔记(七)const和指针
  10. python操作sqlite3 导入csv文件_[转载]SQLite 3导入导出成txt或csv操作
  11. pythonflask框架_Flask框架
  12. HTML+CSS+JS实现 ❤️透明的水滴文字背景特效❤️
  13. mysql如何撤销上一条指令_mysql命令行,多行命令时如何取消/返回修改前边的命令...
  14. NFS双机热备探究实验
  15. Atitit.加密算法 des  aes 各个语言不同的原理与解决方案java php c#
  16. Unity3D模型中的SubMesh
  17. zepto-selector.js简单分析
  18. 标签体系下的用户画像建设小指南
  19. Spark学习-入门介绍
  20. Hadoop-感知网络布局和机架的设计

热门文章

  1. 语音识别-人工智能实验室旗下语音识别频道,汇集最新最全的语音识别新闻及资讯,让您掌握语音识别第一手的资讯-中国人工智能网-Powered by www.AiLab.cn
  2. c++成员函数指针揭秘
  3. Codeforces Round 649 (Rated for Div. 2)D. Ehab s Last Corollary详细题解(图论+简单环)
  4. pytorch之torch.nn.Conv2d()函数详解
  5. syscall(SyS_gettid)
  6. DRF-视图类APIView与GenericAPIView
  7. Latex 表格文字居中(垂直和水平居中)
  8. 爬虫大佬,把他总结的正则表达式使用给我了!
  9. 域名使用HTTPS的相关配置
  10. Android实现snmp协议(一)