Android学习笔记(八)深入分析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">
3 </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,日志如下:
七、总结
启动Service和停止Service是一一对应的,绑定Service和解绑Servcie是一一对应的,如果同时启动和绑定了Service,必须通过解绑和停止Service才能使该Service真正停止。
声明:欢迎转载,转载时请注明本文链接。
Android学习笔记(八)深入分析Service启动、绑定过程的更多相关文章
- Android学习笔记_23_服务Service之AIDL和远程服务实现进程通信以及进程间传递自定义类型参数
一.了解AIDL语言: 在Android中, 每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢? 显然, Java中是不支持跨进程内存共享的.因此要传递对象, 需要把对象解析 ...
- Android学习笔记九:Service
一:Service是什么 Service,服务.一般用于提供需要在后台长期运行的服务(如复杂计算.下载等等耗时任务),其特点是长生命周期的.没有用户界面.在后台运行的. 二:Service的生命周期方 ...
- Android学习笔记_22_服务Service应用之—与Activity进行相互通信的本地服务
一.启动服务的两种方法方法: 第一种: startService()和stopService()启动关闭服务.适用于服务和Activity之间没有调用交互的情况.如果相互之间需要方法调用或者传递参数 ...
- android学习笔记八——SeekBar
SeekBar——拖动条 拖动条(SeekBar)组件与ProgressBar水平形式的显示进度条类似,不过其最大的区别在于,拖动条可以由用户自己进行手工的调节,例如当用户需要调整播放器音量或者电影的 ...
- Android学习笔记八:用Broadcast Receiver跨进程(跨app)通信
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7515194.html 在前面介绍四大组件的时候提到了可以对外部事件进行过滤的Broadcast Receive ...
- 【转】 Pro Android学习笔记(七七):服务(2):Local Service
目录(?)[-] Local service代码 调用Local ServiceLocal Service client代码 AndroidManifestxml定义Serviceacitivty的l ...
- 【转】 Pro Android学习笔记(八二):了解Package(1):包和进程
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在之前,我们已经学习了如何签发apk,见P ...
- 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件
目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...
- 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...
- 【转】 Pro Android学习笔记(八八):了解Handler(2):什么是Handler
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 之前我们有一篇很好的博文<Andro ...
随机推荐
- C++写一个排列组合小程序
今天突然想到一个问题,有时候,针对同一个事件有多种反映,特别是游戏AI当中,这种情况下需要采取最适合的方案,哪种方案最适合,可以将每种方案的结果或影响都计算一遍,从而选择最合适的.最基本就是一个排列组 ...
- LeetCode OJ学习
一直没有系统地学习过算法,不过算法确实是需要系统学习的.大二上学期,在导师的建议下开始学习数据结构,零零散散的一学期,有了链表.栈.队列.树.图等的概念.又看了下那几个经典的算法——贪心算法.分治算法 ...
- 一个供新手把玩的jQueryUI在线文档
最近整理了一份jQueryUI文档,方便以后学习和运用. 把玩地址
- JavaScript的问题
定义一个函数function, function testParams() { var params = ""; for(var i=0; i<arguments.lengt ...
- CSS3之简易的3D模型构建[原创开源]
CSS3之简易的3D模型构建[开源分享] 先上一张图(成果图):这个是使用 3D建模空间[源码之一] 制作出来的模型之一 当然这是一部分模型特写, 之前还制作过枪的3D模型等等. 感兴趣的朋友可以自己 ...
- js 中用Dom2级事件处理函数(改变样式)
下面这些客户端 javascript代码用到了事件,它给一个很重要的事件--“load" 事件注册了一个事件处理程序.同时展示了注册”click“事件处理函数更高级的一种方法 <!do ...
- 分享一下 Eclipse 插件 PyDev 的安装
想趁暑假学习一下python,学好语言好的开发环境是基础.因为安装有eclipse,所以想安装PyDev插件作为python开发环境.本来以为是一件简单的事情,结果整整弄了一下午各种装不上,度娘上的几 ...
- C# 使用Salt+Hash来为密码加密
(一) 为什么要用哈希函数来加密密码 如果你需要保存密码(比如网站用户的密码),你要考虑如何保护这些密码数据,象下面那样直接将密码写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到 ...
- Delphi XE5 Device compatibility
Delphi XE5 Device compatibility https://docs.google.com/spreadsheet/ccc?key=0AoEN2CEsVvJ0dGhVaWJE ...
- python中的字典(dict),列表(list),元组(tuple)
一,List:列表 python内置的一种数据类型是列表:list.list是一种有序的数据集合,可以随意的添加和删除其中的数据.比如列出班里所有的同学的名字,列出所有工厂员工的工号等都是可以用到列表 ...