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 ...
随机推荐
-
Android随笔之——Android单元测试
在实际开发中,开发android软件的过程需要不断地进行测试.所以掌握Android的单元测试是极其重要的.您应该把单元测试作为Android应用开发周期的一部分,精心编写的测试可以在开发早起帮你发现 ...
-
立flag
lixintong这半年来一直浪啊浪啊都不认真做题!!!!!!简直是太堕落啦!!lixintong非常讨厌这样的lixintong !!! 鉴于lixintong NOIP 完全爆炸啦! lixint ...
-
caffe中的BatchNorm层
在训练一个小的分类网络时,发现加上BatchNorm层之后的检索效果相对于之前,效果会有提升,因此将该网络结构记录在这里,供以后查阅使用: 添加该层之前: layer { name: "co ...
-
background-image小解
body { width: 600px; height: 500px; border: 10px solid #789; margin: 10px 100px; padding: 40px; back ...
-
怎么在Centos7下添加win8.1的启动项
首先找到启动文件. 在/boot/grub2目录下, 找到grub.cfg文件. 然后, sudo修改, 用gedit工具方便. 怎么修改? 打开文件, 找到有两个menuentry开头的部分, 然 ...
-
http下载网页
//http.c #include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/ ...
-
php----------const 定义的常量和define()定义的常量的区别?
用法一:const用于类成员变量,一经定义不可修改,define用于全局常量,不可用于类成员变量的定义,const可在类中使用也可以在类外面使用,define不能. 定义:const 常量名=值; 没 ...
-
错误提示:The project was not built since its build path is incomplete. Cannot find the class file for java.lang.Object. Fix the build path then try building this project The type java.lang.Object cannot b
原文:http://www.cnblogs.com/mmzs/p/7662863.html 错误类型: 搞了很久才找到原因.解决办法写出来分享: 出现以上错误的原因是玩耍maven时多装了个jre.本 ...
-
初心不负 笔记-JS高级程序设计-引用类型篇-Array
ES3方法集合: 1join()方法,将一个数组里面的所有元素转换成字符串,然后再将他们连接起来返回一个字符串,通过制定的符号,默认值为逗号.不会改变原数组 ,,,,]; a.join(); &quo ...
-
[html]自定义滚动条风格
webkit: <style type="text/css"> *{ margin: 0; padding: 0; } ::-webkit-scrollbar { wi ...