Service 使用详解
极力推荐文章:欢迎收藏
Android 干货分享
阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android
本篇文章主要介绍 Android
开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:
- Service 简介
- 四大组件之一,必须在Androidmainfest.xml 中注册
- 启动模式启动服务
- 绑定模式绑定服务
- 前台服务
- AIDL远程服务
Service
是Android
四大组件之一(Activity
活动,Service
服务,ContentProvider
内容提供者,BroadcastReceiver
广播),与Activity
相比,Activity
是运行在前台,用户可以看得见,Service
则是运行在后台,无用户界面,用户无法看到。
Service
主要用于组件之间交互(例如:与Activity
、ContentProvider
、BroadcastReceiver
进行交互)、后台执行耗时操作等(例如下载文件,播放音乐等,但Service
在主线程运行时长不能超过20s
,否则会出现ANR
,耗时操作一般建议在子线程中进行操作)。
1.Service 简介
在了解Service
的生命周期的之前,我们先了解一下Service
的继承关系,方便我们更好的了解Service
。
Service 继承关系如下:
java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.app.Service
Service 的两种启动模式
Service
有两种不同的启动模式 ,不同的启动模式对应不同生命周期.
Service
启动模式主要分两种: 1. 启动模式。 2. 绑定模式。
1.启动模式
此模式通过 startService()
方法启动,此服务可以在后台一直运行,不会随启动组件的消亡而消亡。只能执行单一操作,无法返回结果给调用方,常用于网络下载、上传文件,播放音乐等。
2.绑定模式
此模式 通过绑定组件(Activity
等)调用 bindService()
启动,此服务随绑定组件的消亡而解除绑定。
如果此时没有其它通过startService()
启动,则此服务会随绑定组件的消亡而消亡。
多个组件不仅可以同时绑定一个Service
,而且可以通过进程间通信(IPC)
执行跨进程操作等。
3.两种服务可以同时运行
启动模式与绑定模式的服务可以同时运行,在销毁服务时,只有两种模式都不在使用Service
时候,才可以销毁服务,否则会引起异常。
4. 两种 Service 模式的生命周期
两种 Service
模式的生命周期如下:
2.四大组件之一,必须在Androidmainfest.xml 中注册
Service 注册方法如下:
<manifest ... >
...
<application ... >
<service android:name=".ServiceMethods" />
...
</application>
</manifest>
注意:
Service
如不注册 ,不会像Activity
那样会导致App Crash
,Service
不注册 不会报异常信息,但是服务会起不来,如不注意很容易迷惑。
3.启动模式
通过启动模式启动的Service
,如不主动关闭,Service
会一直在。
启动模式启动服务的方法
Intent mBindIntent = new Intent(ServiceMethods.this, BindServiceMethods.class);
startService(mStartIntent);
启动模式启动服务的生命周期
下面是验证启动模式启动服务的生命周期的方法,详细生命周期请查看上方Service
的生命周期图。
01-03 17:16:36.147 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onCreate----
01-03 17:16:36.223 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onStartCommand----
01-03 17:16:38.174 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onDestroy----
启动模式 启动服务案例
此案例功能:启动服务,在服务中创建通知
// Service 创建方法
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "----onCreate----");
}
// Service 启动方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "----onStartCommand----");
// 获取NotificationManager实例
notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// 实例化NotificationCompat.Builder并设置相关属性
NotificationCompat.Builder builder = new NotificationCompat.Builder(
this)
// 设置小图标
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(
BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher))
// 设置通知标题
.setContentTitle("我是通过StartService服务启动的通知")
// 设置通知不能自动取消
.setAutoCancel(false).setOngoing(true)
// 设置通知时间,默认为系统发出通知的时间,通常不用设置
// .setWhen(System.currentTimeMillis())
// 设置通知内容
.setContentText("请使用StopService 方法停止服务");
// 通过builder.build()方法生成Notification对象,并发送通知,id=1
notifyManager.notify(1, builder.build());
return super.onStartCommand(intent, flags, startId);
}
// Service 销毁方法
@Override
public void onDestroy() {
Log.i(TAG, "----onDestroy----");
notifyManager.cancelAll();
super.onDestroy();
}
4. 绑定模式启动绑定服务
绑定模式启动的服务会随着绑定逐渐的消亡而解除Service
绑定,如果此时Service
没有通过启动模式启动,则此服务将会被销毁。
绑定模式启动绑定服务的方法
绑定模式,是通过其他组件启动的Service
。
启动绑定模式服务的方法
// 启动绑定服务处理方法
public void BtnStartBindService(View view) {
// 启动绑定服务处理方法
bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
isBindService = true;
Toast.makeText(ServiceMethod.this, "启动 " + mBindCount + " 次绑定服务",
Toast.LENGTH_SHORT).show();
}
public void BtnSopBindService(View view) {
if (isBindService) {
// 解除绑定服务处理方法
unbindService(serviceConnection);
Toast.makeText(ServiceMethod.this, "解除 " + mUnBindCount + " 次绑定服务",
Toast.LENGTH_SHORT).show();
isBindService = false;
}
}
绑定服务 随绑定组件的消亡而消亡
绑定模式 生命周期回调代码如下:
// Service 创建方法
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "----onCreate----");
}
// Service 绑定方法
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "----onBind----");
MyBinder myBinder = new MyBinder();
return myBinder;
}
// Service 解除绑定方法
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "----onUnbind----");
return super.onUnbind(intent);
}
// Service 销毁方法
@Override
public void onDestroy() {
Log.i(TAG, "----onDestroy----");
super.onDestroy();
}
绑定服务的生命周期代码打印Log
信息如下:
01-03 20:32:59.422 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onCreate----
01-03 20:32:59.423 13306-13306/com.android.program.programandroid I/BindService wjwj:: -----onBind-----
01-03 20:33:09.265 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onUnbind----
01-03 20:33:09.266 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onDestroy----
绑定服务案例
功能:获取绑定模式启动 绑定服务及解除绑定服务的次数
绑定服务类
package com.android.program.programandroid.component.Service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class BindServiceMethods extends Service {
private static final String TAG = "BindService wjwj:";
public BindServiceMethods() {
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "----onCreate----");
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "----onBind----");
MyBinder myBinder = new MyBinder();
return myBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "----onUnbind----");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.i(TAG, "----onDestroy----");
super.onDestroy();
}
}
- 组件与绑定服务类之间的交互
// 启动绑定服务处理方法
public void BtnStartBindService(View view) {
bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
isBindService = true;
Toast.makeText(ServiceMethods.this,"启动 "+mBindCount+" 次绑定服务",Toast.LENGTH_SHORT).show();
}
// 解除绑定服务处理方法
public void BtnSopBindService(View view) {
if (isBindService) {
unbindService(serviceConnection);
Toast.makeText(ServiceMethods.this,"解除 "+mUnBindCount+" 次绑定服务",Toast.LENGTH_SHORT).show();
isBindService=false;
}
}
- 组件之间交互所需的
Binder
接口类
/**
* 该类提供 绑定组件与绑定服务提供接口
* */
public class MyBinder extends Binder {
private int count = 0;
public int getBindCount() {
return ++count;
}
public int getUnBindCount() {
return count> 0 ? count-- : 0;
}
}
5. 提高服务的优先级
服务默认启动方式是后台服务,但是可以通过设置服务为前台服务,提高服务的优先级,进而避免手机内存紧张时,服务进程被杀掉。
设置前台服务的两种方法
1.设置为前台服务
//设置为前台服务
startForeground(int, Notification)
2.取消前台服务
//取消为前台服务
stopForeground(true);
startForeground 前台服务案例
功能:前台服务绑定通知信息,提高服务进程优先级,否则取消通知信息
package com.android.program.programandroid.component.Service;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import com.android.program.programandroid.R;
public class MyStartForcegroundService extends Service {
public MyStartForcegroundService() {
}
@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();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals("start_forceground_service")) {
// 获取NotificationManager实例
NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// 实例化NotificationCompat.Builder并设置相关属性
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
// 设置小图标
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
// 设置通知标题
.setContentTitle("我是通过startForeground 启动前台服务通知")
// 设置通知不能自动取消
.setAutoCancel(false)
.setOngoing(true)
// 设置通知时间,默认为系统发出通知的时间,通常不用设置
// .setWhen(System.currentTimeMillis())
// 设置通知内容
.setContentText("请使用stopForeground 方法改为后台服务");
//通过builder.build()方法生成Notification对象,并发送通知,id=1
// 设置为前台服务
startForeground(1, builder.build());
} else if (intent.getAction().equals("stop_forceground_service")) {
stopForeground(true);
}
return super.onStartCommand(intent, flags, startId);
}
}
6. 使用AIDL接口实现远程绑定
由于内容较多,后续另开一篇详细介绍。
至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!
Service 使用详解的更多相关文章
- Android中Service(服务)详解
http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...
- 【转载】Android Studio Service AIDL 详解
公司产品之前IM这块存在很多问题,消息到达率低,加上协议上有些问题,丢消息频繁,所以需要重构IM,AIDL不能解决以上问题.好吧!那AIDL可以解决什么问题?什么是AIDL? 什么是AIDL? AID ...
- Kubernetes K8S之Service服务详解与示例
K8S之Service概述与代理说明,并详解所有的service服务类型与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master Cent ...
- Service通信详解
1.使用Intent进行异步通讯 在Service任务一旦完成后,就发送广播.开发者只需要实现一个BroadcastReceiver来监听响应既可. Activity.startService启动in ...
- [Android] Service服务详解以及如何使service服务不被杀死
排版上的细节有些不好看,主要是我用的MarkDown编辑器预览和这里的不一样,在那个上面的样式很舒服.这里要改的地方太多就不想改了,将就看吧.下次写的时候注意.还有看到错误给我提啊. 本文链接:htt ...
- linux centos service 参数详解
Service文件 开门见山,直接来看两个实际的服务配置文件吧. 第一个配置是 CoreOS 系统中 Docker 服务的 Unit 文件,路径是 /usr/lib/systemd/system/do ...
- Android中Service 使用详解(LocalService + RemoteService)
Service 简介: Service分为本地服务(LocalService)和远程服务(RemoteService): 1.本地服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外L ...
- Android AIDL SERVICE 双向通信 详解
http://www.cnblogs.com/punkisnotdead/p/5062631.html 起因 是这个blog 提到了 用webview 的时候 用开启子进程的方式 可以极大避免内存泄露 ...
- Windows Service 之 详解(一)
一.Windows 服务简介 Windows 服务是可以在系统启动时自动打开的(不需要任何人登录计算机)的程序. 1.适合创建Windows 服务的场景: [1] 在没有用户交互操作的情况下运行程序: ...
- Metadata Service 架构详解 - 每天5分钟玩转 OpenStack(165)
下面是 Metadata Service 的架构图,本节我们详细讨论各个组件以及它们之间的关系. nova-api-metadata nova-api-metadata 是 nova-api 的一个子 ...
随机推荐
- Android 上传开源项目到 jcenter 实战踩坑之路
本文微信公众号「AndroidTraveler」首发. 背景 其实 Android 上传开源项目到 jcenter 并不是一件新鲜事,网上也有很多文章. 包括我本人在将开源项目上传到 jcenter ...
- js深入(四)万脸懵圈的this指向
作为一个js菜鸡的我而言,在之前讲到过那么多的js链式查找机制,比如说原型链,作用域链等等,想当然的把这个机制带入到了this指向上边,结果就是这个this指向指的我万脸懵逼(标题换字了,担心被河蟹) ...
- Codeforces 755A:PolandBall and Hypothesis(暴力)
http://codeforces.com/problemset/problem/755/A 题意:给出一个n,让你找一个m使得n*m+1不是素数. 思路:暴力枚举m判断即可. #include &l ...
- 淺談Coach思考模式
我現在是個窮屌,沒錯.我清楚的知道這一點,但是我也知道,我能改變. 之前幹了7年的評估行業,中間換了3家公司,第一家公司待的時間最長,待了5年.2018年開始,我就在思考轉行.之前在第一家企業接觸過一 ...
- NDK_OVERVIEW翻译
Android NDK Overview Introduction: The Android NDK is a set of tools that allows Android application ...
- 如何在vue中监听scroll,从而实现滑动加载更多
首先需要明确3个定义: 文档高度:整个页面的高度 可视窗口高度:你看到的浏览器可视屏幕高度 滚动条滚动高度: 滚动条下滑过的高度 当 文档高度 = 可视窗口高度 + 滚动条高度 时,滚动条正好到底. ...
- 用MATLB仿真一个单闭环控制量,同时还存在两个开环控制变量的阶跃响应曲线。(自动控制方法是PID中的P控制。通过查表法直接给开环参数稳态最佳的大小)
实际项目背景:甘肃省,航天510所的LIPS100电推力器.一共有三个控制变量,开环控制变量是:Ia(阳极电流).mmrf(阳极主流率) 这个阳极主流率是阀门变量,不能够突变,模拟用(大学一年级课,电 ...
- .net持续集成cake篇之cake任务依赖、自定义配置荐及环境变量读取
系列目录 新建一个构建任务及任务依赖关系设置 上节我们通过新建一个HelloWorld示例讲解了如何编写build.cake以及如何下载build.ps1启动文件以及如何运行.实际项目中,我们使用最多 ...
- samrt210开发板ping-系列问题(开发板ping通主机,主机ping通虚拟机,唯独~开发板ping不通虚拟机)
硬件:PC机.虚拟机(Linux).开发板(smart210) 常用模型: 注:1).有线网卡与无线网不可同连一个路由器,不可在同网段: 2).vmware选择桥接模式,虚拟网络适配器选定具体的网卡名 ...
- c# HttpWebResponse 各种情况下 获取StatusCode状态码
捕捉网页出现404.500等会直接抛出WebException异常 异常代码: (HttpWebResponse)req.GetResponse(); 当执行这段代码出现异常 解决问题 那如果我们想获 ...