一 Service简介

Service是Context的子类

Service是四大组件之一 用来在后台处理一些比较耗时的操作或者去执行某些需要长期运行的任务

二 注意

Service里面不能直接执行耗时的操作 因为Service里面所有方法执行都是在主线程

如果要执行耗时的操作 开启子线程

三 Service特点

1. 没有界面

2. 在后台长时间的运行

3. 无法自己启动

4. 单例模式

四 新建一个Service

1. 继承Service

public class MyService extends Service {

    @Override
public void onCreate() {
super.onCreate();
Log.i("HUANG", "onCreate");
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("HUANG", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
} @Nullable @Override
public IBinder onBind(Intent intent) {
Log.i("HUANG", "onBind");
return null;
} @Override
public boolean onUnbind(Intent intent) {
Log.i("HUANG", "onUnbind");
return super.onUnbind(intent);
} @Override
public void onDestroy() {
super.onDestroy();
Log.i("HUANG", "onDestroy");
} }

2. AndroidManifest.xml application节点里面配置service name属性必须配置 其余可选

<service android:name=".service.MyService" />

3. 启动Service startService()或者bindService()

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    ServiceConnection mConnection; //服务的连接对象

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); findViewById(R.id.start).setOnClickListener(this);
findViewById(R.id.stop).setOnClickListener(this);
findViewById(R.id.bind).setOnClickListener(this);
findViewById(R.id.unbind).setOnClickListener(this);
} @Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
startService(new Intent(this, MyService.class));
break; case R.id.stop:
stopService(new Intent(this, MyService.class));
break; case R.id.bind:
Intent service = new Intent(this, MyService.class);
mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {} @Override
public void onServiceDisconnected(ComponentName name) {}
};
bindService(service, mConnection, Context.BIND_AUTO_CREATE);
break; case R.id.unbind:
unbindService(mConnection);
break;
}
} }

五 Service生命周期

Service生命周期会因为启动方式不一样而不同 停止Service的方式也不同

当采用startService()方法启动 与之有关的生命周期方法

onCreate() -> onStartCommand() -> onDestroy()

onCreate() 该方法在Service被创建时调用 只会被调用一次 无论调用多少次startService()方法和bindService()方法 Service也只被创建一次

onStartCommand() 只有采用startService()方法启动时才会回调该方法 该方法在Service开始运行时被调用 多次调用startService()方法尽管不会多次创建Service 但onStartCommand()方法会被多次调用

onDestroy() 该方法在Service被销毁时调用

只要调用一次stopService()方法便可以停止Service 无论之前它被调用了多少次的启动Service方法

当采用bindService()方法启动 与之有关的生命周期方法

onCreate() -> onBind() -> onUnbind() -> onDestroy()

onCreate() 该方法在Service被创建时调用 只会被调用一次 无论调用多少次startService()方法和bindService()方法 Service也只被创建一次

onBind() 只有采用bindService()方法启动时才会回调该方法 该方法在调用者与Service绑定时被调用 当调用者与Service已经绑定 多次调用bindService()方法并不会导致该方法被多次调用

onUnbind() 只有采用bindService()方法启动时才会回调该方法 该方法在调用者与Service解除绑定时被调用

onDestroy() 该方法在Service被销毁时调用

只要调用一次unbindService()方法便可以停止Service 多次调用会报错

如果一个Activity已经bindService() 那么Activity退出一定要unbindService() 否则报错

多个客户端可以绑定同一个Service 如果Service还未被启动 bindService()方法可以启动Service

如果先采用startService()方法启动 接着又采用bindService()方法启动(此处startService()和bindService()没有先后顺序)

这个时候单独执行 stopService()或者unbindService() Service都不会被销毁

只有先执行stopService() 接着又执行unbindService() Service才会被销毁(此处stopService()和unbindService()没有先后顺序)

也就是说 一个Service必须要在两种启动方式都停止的情况下才会被销毁

六 startService()和bindService()区别

1. 导致Service的生命周期不同

2. 停止Service的方式不同

3. startService()启动的Service 在系统正在运行的服务中可以找到  bindService()启动的Service 在系统正在运行的服务中找不到

4. startService()调用者和Service是没有关系的 即使调用者退出了 Service仍然运行  bindService()调用者和Service是绑定在一起的 调用者一旦退出 Service也就终止 "同生共死"

七 startService()和bindService()应用场景

通过startService()和stopService()启动关闭Service 适用于调用者和Service之间没有交互的情况

通过bindService()和unbindService()启动关闭Service 适用于调用者和Service之间需要方法调用或者传递参数

八 线程 进程 服务

线程: 是CPU执行的一个最小单元

进程: 是系统里面的一个最小单元 一个应用可以理解为一个进程 用户启动一个应用程序 操作系统就会为其分配一块内存空间 CPU去启动进程里面的主线程

服务: 服务不是线程 服务也不是进程 服务运行在进程里面(https://developer.android.com/reference/android/app/Service#WhatIsAService)

九 进程的优先级别

Android系统试图尽可能长的保持一个应用程序进程 只有内存不足的时候 系统才会杀死进程

杀死进程是根据进程的优先级别 先杀级别低的

进程的优先级别排序 前台进程 > 可视进程 > 服务进程 > 后台进程 > 空进程

1. 前台进程(用户当前工作所需要的 一个进程如果满足下列任何条件被认为是前台进程)

  1.1 运行着一个正在与用户交互的Activity(onResume()方法已经被调用)

  1.2 寄宿着一个Service 该Service绑定到了一个与用户交互的Activity

  1.3 有一个Service对象正在执行生命周期方法

  1.4 有一个BroadcastReceiver对象正在执行生命周期方法

2. 可视进程(没有任何前台组件 但是仍然能影响用户在屏幕上看到东西 一个进程如果满足下列任何条件被认为是可视进程)

  2.1 寄宿着一个不是前台的Activity 但是它对用户仍可见(onPause()方法已经被调用)

  2.2 寄宿着一个Service 该Service绑定到了一个可视的Activity

3. 服务进程(在后台 应用里面有一个用startService()方法启动的服务在运行)

4. 后台进程(在后台 任务栈里面有Activity)

5. 空进程(在后台 任务栈里面没有Activity)

前台进程和可视进程难以被杀 服务进程要保活 后台进程和空进程被杀了影响不大

把服务进程提升为前台进程

public class MyService extends Service {

    @Override
public void onCreate() {
super.onCreate(); /**
* Intent未指定Activity 无跳转
*
* Intent已指定Activity
* 应用在后台 跳转到指定Activity 当指定Activity退出时 不管点击通知前是在哪个页面 都会回到本应用栈顶页面
* 应用不在后台 跳转到指定Activity 当指定Activity退出时 回到点击通知前的那个页面
* 注意: 指定Activity也受启动模式限制
* */
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
99, //requestCode
intent,
PendingIntent.FLAG_UPDATE_CURRENT); //更新 同一个id并且同一个requestCode的PendingIntent NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher) //状态栏显示的小图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) //下拉显示的大图标
.setTicker("滴滴") //首次出现在通知栏 带上升动画效果
.setContentTitle("ContentTitle") //标题
.setContentText("ContentText") //内容
.setWhen(System.currentTimeMillis()) //通知产生的时间 会在通知信息里显示
.setContentInfo("ContentInfo") //显示信息
.setPriority(NotificationCompat.FLAG_FOREGROUND_SERVICE) //设置通知优先级
.setDefaults(Notification.DEFAULT_ALL) //设置通知默认的声音 震动 呼吸灯
.setAutoCancel(false) //点击和清理可以去掉通知
.setOngoing(true) //设置为一个正在进行的通知 通常是用来表示一个后台任务(如播放音乐 文件下载)
.setContentIntent(pendingIntent); // 把服务进程提升为前台进程
startForeground(100, builder.build());
} @Nullable @Override
public IBinder onBind(Intent intent) {
return null;
} }

如果要保证一个应用在后台不被杀死 可以先在应用里面采用startService()方法启动一个服务 再把服务进程提升为前台进程

Android Service(下)

Android Service(上)的更多相关文章

  1. Android Service(下)

    阅读本文需要先阅读Android Service(上) 一 为什么需要bindService() 绑定服务就是为了和服务进行通讯 可以调用服务里面的方法 二 bindService()调用服务里面方法 ...

  2. Android Service完全解析,关于服务你所需知道的一切(上)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...

  3. Android Service(上)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...

  4. Android Service完全解析,关于服务你所需知道的一切(上)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...

  5. (转) Android Service完全解析,关于服务你所需知道的一切(上)

    相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序 ...

  6. Android Service完全解析,关于服务你所需知道的一切(上) (转载)

    转自:http://blog.csdn.net/guolin_blog/article/details/11952435 转载请注明出处:http://blog.csdn.net/guolin_blo ...

  7. Android Service完全解析(上)

    转载:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Androi ...

  8. android Service介绍

    一.简介 android中service(服务)运行于后台,没有界面.和其他组件一样,service也运行在主线程中,因此不能用它来做耗时的请求或者动作.可以在服务中开启线程,在线程中做耗时操作.可以 ...

  9. 非root Android设备上Tcpdump的实现

    通常我们在Android应用中执行某个命令时会使用"Runtime.getRuntime().exec("命令路径")"这种方式,但是当我们执行抓包操作时,使用 ...

随机推荐

  1. 【http学习杂记】2017年7月14日

    1. 连接超时 连接超时是tcp协议层次, 此时服务器还没有处理请求数据,也就是说服务器的逻辑开没有执行 2. 请求超时 请求超时属于服务器已经连接成功并开始处理,但是时间比较长,大于你设置的请求超时 ...

  2. Python的多线程理解,转自虫师https://www.cnblogs.com/fnng/p/3670789.html

    多线程和多进程是什么自行google补脑 对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂.所以,这里力图用简单的例子,让你对多线程有个初步的认识. 单线程 在好些年前的 ...

  3. OSM

    一.OSM是什么 开放街道图(OpenStreetMap,简称OSM)是一个网上地图协作计划,目标是创造一个内容自由且能让所有人编辑的世界地图(wiki:http://wiki.openstreetm ...

  4. BZOJ4241:历史研究(回滚莫队)

    Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...

  5. 1305. [CQOI2009]跳舞【最大流+二分】

    Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会 ...

  6. 1834. [ZJOI2010]网络扩容【费用流】

    Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求:  1.在不扩容的情况下,1到N的最大流:  2.将1到N的最大流增加K所需 ...

  7. 上手 Kubernetes

    一.Kubernetes架构 二.重要的几个概念 1.Pod:最小单元 1.1 一个Pod里可以有多个Container 1.2这些container共享这个pod的同一个网络地址,同一个文件系统,通 ...

  8. jdk8中tomcat修改配置PermSize为MetaspaceSize 标签: tomcatPermSizeMetaspaceSize

    JDK8中用metaspace代替permsize,因此在许多我们设置permsize大小的地方同样需要修改配置为metaspace 将-XX:PermSize=200m;-XX:MaxPermSiz ...

  9. java 控制流

    一:     块作用域 块(即复合语句):是指由一对花括号括起来的若干条简单的java语句.块决定了变量的作用域,一个块可以嵌套在另一个块中,如下: public class print_In { p ...

  10. Spring整合MyBatis(五)MapperScannerConfigurer

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 目录 一.processPropertyPlaceHolders属性的 ...