深入分析Service启动、绑定过程
Service是Android中一个重要的组件,它没有用户界面,可以运行在后太做一些耗时操作。Service可以被其他组件启动,甚至当用户切换到其他应用时,它仍然可以在后台保存运行。Service 是Android四大组件中与Activity最相似的组件,都代表可执行的程序,区别在于:Service一直运行在后台,没有界面,一旦Service被启动,即完全具有自己的生命周期。
一、创建一个Service
在创建Service时,步骤与Activity很像:
1.继承Service,创建Service子类。
2.在AndroidManifest.xml文件中配置该Service。
下面创建一个最基本的Service组件:
MyService.java
public class MyService extends Service { //必须实现的方法,用户返回Binder对象
@Override
public IBinder onBind(Intent intent) {
System.out.println("--onBind()--");
return null;
} //创建Service时调用该方法,只调用一次
@Override
public void onCreate() {
super.onCreate();
System.out.println("--onCreate()--");
} //每次启动Servcie时都会调用该方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("--onStartCommand()--");
return super.onStartCommand(intent, flags, startId);
} //解绑Servcie调用该方法
@Override
public boolean onUnbind(Intent intent) {
System.out.println("--onUnbind()--");
return super.onUnbind(intent);
} //退出或者销毁时调用该方法
@Override
public void onDestroy() {
System.out.println("--onDestroy()--");
super.onDestroy();
} }
然后再Manifest.xml文件中红配置一下
<service
android:name=".MyService">
</service>
为了待会测试的方便,我们在该Service的onCreate()方法里面写一个方法,开启一个线程,让其不断输出“Service运行中”的状态。补充后的MyService类如下:
public class MyService extends Service { private boolean serviceRunning = false;
// 必须实现的方法,用户返回Binder对象
@Override
public IBinder onBind(Intent intent) {
System.out.println("--onBind()--");
return null;
} // 创建Service时调用该方法,只调用一次
@Override
public void onCreate() {
super.onCreate();
System.out.println("--onCreate()--");
serviceRunning = true;
new Thread() {
@Override
public void run() {
while (serviceRunning) {
System.out.println("---Service运行中---");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
} // 每次启动Servcie时都会调用该方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("--onStartCommand()--");
return super.onStartCommand(intent, flags, startId);
} // 解绑Servcie调用该方法
@Override
public boolean onUnbind(Intent intent) {
System.out.println("--onUnbind()--");
return super.onUnbind(intent);
} // 退出或者销毁时调用该方法
@Override
public void onDestroy() {
serviceRunning = false;
System.out.println("--onDestroy()--");
super.onDestroy();
} }
代码分析:首先我们定义一个boolean类型的变量serviceRunning,用来控制新线程中是否输出“---Service运行中---”,通过这样的方式更能让我们直观地看到Servcie的运行状态。
二、启动Service
启动Service和启动一个Activity类似,也是先定义一个Intent让它指向需要启动Service,然后通过调用startService()方法,启动即可,具体代码如下:
btn_start_service.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
intent = new Intent(this, MyService.class);
startService(intent);
}
});
代码分析:在主界面中添加了一个按钮,在按钮中首先定义了一个Intent,然后通过startService启动该Intent从而就可以启动Service,与启动一个Activity的方法简直一样啊。
三、停止Service
与启动Service相对应的就是停止Service,通过stopService()即可完成此操作,如下:
btn_stop_service.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
stopService(intent);
}
});
当然,这里Intent需要与startService使用的为一个。
四、绑定Service
绑定Service用是通过调用bindService(Intent service, ServiceConnection conn, int flags)方法来实现的,单看参数就知道与启动Service比起来,会麻烦一些,大体分为如下三步:
第一步:重写onBind()方法,返回Service实例
Service可以让Activity绑定,以获得更加详细的接口。如果先想让一个Service支持绑定,需要实现Service中得onBind()方法,并返回被绑定Service的当前实例,如下:
public IBinder onBind(Intent intent) {
System.out.println("--onBind()--");
return new MyBinder();
} public class MyBinder extends Binder{
MyService getService(){
return MyService.this;
}
第二步:实现一个ServiceConnection
另外,Service和其他组件的链接表示为一个ServiceConnection,要想一个Service和其他组件绑定,需要实现一个新的ServiceConnection,建立一个链接后,就可以通过重写onServiceConnected()方法和onServiceDisconnected()方法,来获得对Service实例的引用。代码如下:
MyService.MyBinder binder = null;
class MyServiceConn implements ServiceConnection {
// 服务被绑定成功之后执行
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//service为onBind方法返回的Service实例
binder = (MyService.MyBinder) service;
} // 服务奔溃或者被杀掉执行
@Override
public void onServiceDisconnected(ComponentName name) {
binder = null;
}
}
第三步:调用bindService执行绑定Service
要想绑定需要给bindService()除了需要给他传递一个需要的Intent和一个ServiceConnection实例外,还需要指定一个标示,如下:
btn_bind_service.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
bindService(intent, myServiceConn, Context.BIND_AUTO_CREATE);
}
});
其中,myServiceConn为第二步中MyServiceConn实例,Context.BIND_AUTO_CREATE即为标示。
五、解绑Service
解绑Service是通过unbindService实现的,如下:
btn_unbind_service.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (binder != null) {
unbindService(myServiceConn);
}
}
});
这里需要注意的是,unbindService方法中传入的ServiceConnection实例一定要跟绑定时的一致,否则可能会导致程序崩溃。
六、试验
主界面简单,只有四个按钮,如下:
1、当按下startService按钮,然后再按下stopService按钮时,日志如下:
2、当按下bindService,然后再按下unbindService时,日志如下:
3、当按下startService接着按bindService时,这时候就需要unbindService和stopService都按下后才能停止Service,日志如下:
七、总结
1、启动Service和停止Service是一一对应的,绑定Service和解绑Servcie是一一对应的,如果同时启动和绑定了Service,必须通过解绑和停止Service才能使该Service真正停止。
2、应用组件(客户端)可以调用bindService()绑定到一个service.Android系统之后调用service的onBind()方法,它返回一个用来与service交互的IBinder.绑定是异步的.bindService()会立即返回,它不会返回IBinder给客户端.要接收IBinder,客户端必须创建一个ServiceConnection的实例并传给bindService().ServiceConnection包含一个回调方法,系统调用这个方法来传递要返回的IBinder.
声明:欢迎转载,转载时请注明本文链接。
作者:CodingBlock
出处:http://www.cnblogs.com/codingblock/
本文版权归作者和共博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果文中有什么错误,欢迎指出。以免更多的人被误导。
深入分析Service启动、绑定过程的更多相关文章
- Service的绑定过程
--摘自<Android进阶解密> 第一步:ContextImpl到AMS的调用过程 第二步:Service的绑定过程 1)几个与Service相关的对象类型 * ServiceRecor ...
- Android深入四大组件(七)Service的绑定过程
前言 我们可以通过调用Context的startService来启动Service,也可以通过Context的bindService来绑定Service,建议阅读此篇文章前请阅读Android深入四大 ...
- Android学习笔记(八)深入分析Service启动、绑定过程
Service是Android中一个重要的组件,它没有用户界面,可以运行在后太做一些耗时操作.Service可以被其他组件启动,甚至当用户切换到其他应用时,它仍然可以在后台保存运行.Service 是 ...
- Service启动过程分析
Service是一种计算型组件,用于在后台执行一系列的计算任务.由于工作在后台,因此用户是无法直接感知到它的存在.Service组件和Activity组件略有不同,Activity组件只有一种运行模式 ...
- 探索 OpenStack 之(11):cinder-api Service 启动过程分析 以及 WSGI / Paste deploy / Router 等介绍
OpenStack 中的每一个提供 REST API Service 的组件,比如 cinder-api,nova-api 等,其实是一个 WSGI App,其主要功能是接受客户端发来的 HTTP R ...
- 走进JavaWeb技术世界8:浅析Tomcat9请求处理流程与启动部署过程
谈谈 Tomcat 请求处理流程 转自:https://github.com/c-rainstorm/blog/blob/tomcat-request-process/reading-notes &l ...
- Android10_原理机制系列_AMS(ATMS)之应用的第一次启动的过程
概述 该篇基于Android 10的代码.在 AMS之AMS的启动---Android Framework(Android 10) 中已经介绍了,在Android 10中,activity的调度和管理 ...
- AngularJS的启动引导过程
原文:http://www.angularjs.cn/A137?utm_source=ourjs.com 目录: 引导之前 自动引导启动框架 手工引导启动框架 引导第1步:创建注入器 引导第2步:创建 ...
- Service 启动Activity
1, 在BroadcastReceiver中启动Activity的问题 * * 如果在BroadcastReceiver的onReceive()方法中如下启动一个Activity * Inten ...
随机推荐
- wpf tabcontrol内的datagrid的selectionChanged事件向往传递问题
tabcontrol 内的一个tabitem里是datagrid 当程序相应datagrid的selectionchanged事件后会向上传递到tabcontrol的selectionchanged事 ...
- 起手一个mpvue项目准备
1,环境配置(http://mpvue.com/mpvue/quickstart.html) //全局安装vue-cli3脚手架 npm install -g @vue/cli @vue/cli-in ...
- JavaScript中的函数柯里化与反柯里化
一.柯里化定义 在计算机科学中,柯里化是把 接受多个参数的函数 变换成 接受一个单一参数(最初函数的第一个参数)的函数 并且返回 接受余下参数且返回结果的新函数的技术 高阶函数 高阶函数是实现柯里化的 ...
- 安装zabbix需求环境
yum install gcc gcc-c++ make mysql-server mysql-devel libcurl-devel net-snmp-devel php php-ldap php- ...
- Python module中的全局变量
Python module中的全局变量 我想要实现一个python module,这个module中有一些配置项,这些配置项可以被读取,被修改.一个可行的方案是把这些配置项写到一个叫settings. ...
- Windows内核驱动开发入门学习资料
声明:本文所描述的所有资料和源码均搜集自互联网,版权归原始作者所有,所以在引用资料时我尽量注明原始作者和出处:本文所搜集资料也仅供同学们学习之用,由于用作其他用途引起的责任纠纷,本人不负任何责任.(本 ...
- vs2013代码高亮显示失效
问题: 最近使用vs2013写代码的时候经常遇到一种问题,当我们的工程逐渐变大时,突然有一个文件出现以上问题,这并不是设置提示的问题,因为当你打开别的工程时该问题不会出现.这其实是配置缓存的问题,而V ...
- SPSS单一样本的T检验
SPSS单一样本的T检验 如果已知总体均数,进行样本均数与总体均数之间的差异显著性检验属于单一样本的T检验.在SPSS中,单一样本的T检验由"One-Sample T Test"过 ...
- tomcat部署项目报错NoSuchMethodException#addServlet,addFilter
java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet java.lang.NoSuchMethod ...
- class11_messagebox 弹窗
最终的运行效果图(程序见序号2) #!/usr/bin/env python# -*- coding:utf-8 -*-# -------------------------------------- ...