Android——Service介绍与例子
官方定义:Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
Service有两种状态,“启动的”和“绑定”
其中涉及到了Service的两种状态:(Started)、(Bound)
Started:
通过startService()启动的服务处于“启动的”状态,一旦启动,service就在后台运行,即使启动它的应用组件已经被销毁了。通常started状态的service执行单任务并且不返回任何结果给启动者。比如当下载或上传一个文件,当这项操作完成时,service应该停止它本身。
Bound:
“绑定”状态的service,通过调用bindService()来启动,一个绑定的service提供一个允许组件与service交互的接口,可以发送请求、获取返回结果,还可以通过夸进程通信来交互(IPC)。绑定的service只有当应用组件绑定后才能运行,多个组件可以绑定一个service,当调用unbind()方法时,这个service就会被销毁了。
注意:
a.一个服务在进程中的主线程运行——一个服务不会创建自己的线程,也不会在另外的进程运行。
b.还有就是不要把Service理解成线程,你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。举个简单的小例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity 没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。
具体例子:在布局文件中添加两个按钮(启动服务,停止服务),添加点击事件(具体findById获取,再添加监听事件)
创建一个Service类
package com.example.test_myservice_demo01;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("创建服务");
}
@Override
public int onStartCommand(Intent intent,int flags, int startId) {
System.out.println("启动服务..."); //这里实现服务的核心业务
for (int i=0;i<50;i++){
System.out.println("i="+i);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
System.out.println("停止服务");
super.onDestroy();
}
}
MainActivity文件:
...
public void onClick(View v) {
switch (v.getId()){
case R.id.button_start:
Intent startIntent = new Intent(this,MyService.class);
startService(startIntent); //启动服务
break;
case R.id.button_stop:
Intent stopIntent = new Intent(this,MyService.class);
stopService(stopIntent); //停止服务
break;
default:
break;
}
}
在manifest清单文件中可以看到:
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" />
实验结果:如果不点击停止服务,就会一直在运行状态,有什么办法可以能让服务停止下来,只需要在MyService的任何位置调用stopSelf()就能停止服务。
04-17 06:12:36.755 2909-2909/com.example.test_myservice_demo01 I/System.out: 创建服务
04-17 06:12:36.755 2909-2909/com.example.test_myservice_demo01 I/System.out: 启动服务...
04-17 06:12:36.755 2909-2909/com.example.test_myservice_demo01 I/System.out: i=0
04-17 06:12:36.756 2909-2909/com.example.test_myservice_demo01 I/System.out: i=1
04-17 06:12:36.756 2909-2909/com.example.test_myservice_demo01 I/System.out: i=2
04-17 06:12:36.756 2909-2909/com.example.test_myservice_demo01 I/System.out: i=3
...
04-17 06:12:36.757 2909-2909/com.example.test_myservice_demo01 I/System.out: i=47
04-17 06:12:36.757 2909-2909/com.example.test_myservice_demo01 I/System.out: i=48
04-17 06:12:36.757 2909-2909/com.example.test_myservice_demo01 I/System.out: i=49
点击停止按钮后之后
04-17 06:12:43.282 2909-2909/com.example.test_myservice_demo01 I/System.out: 停止服务
...
IntentService服务
这是一个Service的子类,IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。而在一般的继承Service里面如果要进行耗时操作就必须另开线程,但是使用IntentService就可以直接在里面进行耗时操作,因为默认实现了一个worker thread。对于异步的startService请求,IntentService会处理完成一个之后再处理第二个。
例子:
Service类
package com.example.test_myservice_demo01;
import android.app.IntentService;
import android.content.Intent;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p>
* TODO: Customize class - update intent actions and extra parameters.
* 内部类只有一个工作线程来完成耗时操作,只需要实现HandleIntent方法就行
*/
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
System.out.println(intent.getStringExtra("info"));
for (int i =0;i<15;i++){
System.out.println("onHandleIntent-"+i+"-"+Thread.currentThread().getName());
try {
Thread.sleep(500); //模拟延迟
} catch (InterruptedException e) {
e.printStackTrace();
}
// if (i==10){
// stopSelf(); //如果添加,便会停止服务
// break;
// }
}
}
}
MainActivity同上加上一个点击按钮
case R.id.button_3:
Intent startIntentService = new Intent(this,MyIntentService.class);
startIntentService.putExtra("info","这个是 我的第一个IntentService");
startService(startIntentService);
break;
-----------------分割线---------------------------
Bound:还有就是绑定服务、解绑
不同于以上服务,在MainActivity中加按钮点击事件(bind,unbind)
case R.id.button_bind:
Intent intent = new Intent(this,MyBoundService.class);
//异步
bindService(intent,connection, Context.BIND_AUTO_CREATE); //绑定服务
break;
case R.id.button_unbind:
unbindService(connection); //解除服务
break;
还需要:
//绑定服务的连接回调方法
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//绑定成功后回调方法
downloadBinder = (MyBoundService.DownloadBinder) service;
downloadBinder.startDownload();
downloadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName name) {
//服务异常调用
}
};
Service类:
package com.example.test_myservice_demo01;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyBoundService extends Service {
private DownloadBinder mBinder = new DownloadBinder();
class DownloadBinder extends Binder{
public void startDownload(){
Log.d("MyService","startDownload executed");
}
public int getProgress(){
Log.d("MyService","getProgress executed");
return 0;
}
}
public MyBoundService() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mBinder;
// throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("已经解除绑定");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
实验结果:
绑定:
04-17 06:50:08.346 23840-23840/com.example.test_myservice_demo01 D/MyService: startDownload executed
04-17 06:50:08.346 23840-23840/com.example.test_myservice_demo01 D/MyService: getProgress executed
解绑:
04-17 06:50:58.931 23840-23840/com.example.test_myservice_demo01 I/System.out: 已经解除绑定
Android——Service介绍与例子的更多相关文章
- Android service介绍和启动方式
1.Android service的作用: service通常是用来处理一些耗时操作,或后台执行不提供用户交互界面的操作,例如:下载.播放音乐. 2.Android service的生命周期: ser ...
- android Service介绍
一.简介 android中service(服务)运行于后台,没有界面.和其他组件一样,service也运行在主线程中,因此不能用它来做耗时的请求或者动作.可以在服务中开启线程,在线程中做耗时操作.可以 ...
- Android Service总结02 service介绍
Android Service总结02 service介绍 版本 版本说明 发布时间 发布人 V1.0 介绍了Service的种类,常用API,生命周期等内容. 2013-03-16 Skywang ...
- Android Service完全解析,关于服务你所需知道的一切(上)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...
- Android Service(上)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...
- 【Android】详解Android Service
目录结构: contents structure [+] Service简单概述 Service在清单文件中的声明 Service启动服务 Service绑定服务 扩展Binder类 使用Messen ...
- Android Service总结03 之被启动的服务 -- Started Service
Android Service总结03 之被启动的服务 -- Started Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Sky ...
- Android Service完全解析,关于服务你所需知道的一切(上)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...
- [转]Android Service完全解析,关于服务你所需知道的一切
目录(?)[+] Android Service完全解析,关于服务你所需知道的一切(上) 分类: Android疑难解析2013-10-31 08:10 6451人阅读 评论(39) 收藏 举报 ...
随机推荐
- 【转】Android多进程总结一:生成多进程(android:process属性)
前言 正常情况下,一个apk启动后只会运行在一个进程中,其进程名为apk的包名,所有的组件都会在这个进程中运行,以下为DDMS的进程截屏: com.biyou.multiprocess为进程名,也是a ...
- php设计模式-依赖注入模式(Dependency Injection)
依赖注入模式用来减少程序间的耦合.当一个类要使用另一个类时,一般的写法如下: <?php class Test1 { public function say() { echo 'hello'; ...
- mysql锁2
死锁: 指两个事务或者多个事务在同一资源上相互占用,并请求对方所占用的资源,从而造成恶性循环的现象. 出现死锁的原因: 系统资源不足: 进程运行推进的顺序不当: 资源分配不当. 产生死锁的四个必要条件 ...
- 七、Oracle 数据库设计
1. 原始单据与实体之间的关系 可以是一对一.一对多.多对多的关系.在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体. 在特殊情况下,它们可能是一对多或多对一的关系,即一张原始单证 ...
- 吴恩达课后作业学习2-week1-1 初始化
参考:https://blog.csdn.net/u013733326/article/details/79847918 希望大家直接到上面的网址去查看代码,下面是本人的笔记 初始化.正则化.梯度校验 ...
- Edusoho之LAMP环境搭建
主要参考官方文档Ubuntu16.04+Apache+PHP+MySQL+EduSoho 安装教程LAMP环境按照如下搭建是没有问题的,本地虚拟机试验是完全没有问题的. 1.更新 sudo apt-g ...
- 视觉机器学习------KNN学习
KNN(K-Nearest Neighbor algorithm, K最近邻方法)是一种统计分类器,属于惰性学习. 基本思想:输入没有标签即未经分类的新数据,首先提取新数据的特征并与测试集中的每一个数 ...
- 常用的移动前端webapp交互细节
#常用的移动前端webapp交互细节 ##select的表现方式 ###PC端 select控件在传统PC桌面已经存在多年,由于在IE6等低版本浏览器容易造成层级错乱,一直被一些UI框架所抛弃,而用d ...
- 从 0 到 1 实现 React 系列 —— 5.PureComponent 实现 && HOC 探幽
本系列文章在实现一个 cpreact 的同时帮助大家理顺 React 框架的核心内容(JSX/虚拟DOM/组件/生命周期/diff算法/setState/PureComponent/HOC/...) ...
- H5 17-兄弟选择器
17-兄弟选择器 我是标题 我是超链接 我是段落 我是段落 我是段落 我是标题 我是段落 我是段落 我是段落 --> 我是标题 我是超链接 我是段落 我是段落 我是超链接 我是段落 我是标题 我 ...