Services是Android中四大基础组件(Activities、 Services、 Content Providers、 BroadCast Receivers)之一,主要用于在后台长时间运行操作,不提供界面,如音乐播放器,关闭界面后还能继续播放。当页面需要交互时用线程。

创建Services,继承Service,复写里面的方法,用日志显示运行过程:

package com.example.androidservice;import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;public class MyService extends Service {private static final String TAG="TestTag";@Overridepublic IBinder onBind(Intent arg0) {// TODO Auto-generated method stubreturn null;}@Overridepublic void onCreate() {Log.i(TAG, "onCreate");super.onCreate();}@Overridepublic void onStart(Intent intent, int startId) {Log.i(TAG, "onStart");super.onStart(intent, startId);}@Overridepublic void onDestroy() {Log.i(TAG, "onDestroy");super.onDestroy();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.i(TAG, "onStartCommand");return super.onStartCommand(intent, flags, startId);}}

服务生命周期:context.startService() ->onCreate()- >onStart()- >onStartCommand()->Service running ->context.stopService()  ->onDestroy() ->Service stop

如果Service还没有运行,则android先调用onCreate()然后调用onStartCommand(),每次调用startService(Intent)的时候,都会调用执行onStartCommand();
如果Service已经运行,则只调用onStartCommand()。

我们要执行操作可在onStartCommand方法中定义,onStartCommand有4种返回值:

 START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。

START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

创建页面用来启动Services,布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".AndroidServiceActivity" ><Buttonandroid:id="@+id/btnStart"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="开始" ></Button><Buttonandroid:id="@+id/btnStop"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="结束" ></Button></LinearLayout>

开始结束绑定事件,startService来启动服务(调用者与服务之间没有联系,调用都关闭不影响服务运行),stopService来停止服务,注意其参数为Intent对象,所以可以可以通过些Intent传递一些参数给Service,Service可以通过Intent来接收:

package com.example.androidservice;import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;public class AndroidServiceActivity extends Activity {private Button btnStart;private Button btnStop;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_android_service);btnStart=(Button)this.findViewById(R.id.btnStart);btnStop=(Button)this.findViewById(R.id.btnStop);btnStart.setOnClickListener(listener);btnStop.setOnClickListener(listener);}private OnClickListener listener=new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent=new Intent(AndroidServiceActivity.this,MyService.class);switch(v.getId()){case R.id.btnStart:startService(intent);break;case R.id.btnStop:stopService(intent);break;}}};@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_android_service, menu);return true;}}

最后在manifest.xml中添加节点<service android:name=".MyService" />与AndroidServiceActivity的Activity节点同级。

还有一种是用bindService()来启动,通过服务链接(ServiceConnection)或直接获取Service中状态和数据信息 
服务链接能够获取Service的对象,因此绑定Service的组件可以调用Service中的实现的函数 
使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接 
如果在绑定过程中Service没有启动,Context.bindService()会自动启动Service 
同一个Service可以绑定多个服务链接,这样可以同时为多个不同的组件提供服务

创建BindService继承Service,扩展Binder类声明方法getBindService返回BindService,以便调用自定义方法ShowLog()

package com.example.androidservice;import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;public class BindService extends Service {private static final String TAG="BindService";private BindServiceX myBinderServiceX=new BindServiceX();public class BindServiceX extends Binder{public BindService getBindService() {return BindService.this;}}@Overridepublic IBinder onBind(Intent arg0) {// TODO Auto-generated method stubreturn myBinderServiceX;}@Overridepublic void onCreate() {Log.i(TAG, "onCreate");super.onCreate();}@Overridepublic void onStart(Intent intent, int startId) {Log.i(TAG, "onStart");super.onStart(intent, startId);}@Overridepublic void onDestroy() {Log.i(TAG, "onDestroy");super.onDestroy();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.i(TAG, "onStartCommand");return super.onStartCommand(intent, flags, startId);}public void ShowLog(){Log.i(TAG, "BindService=>ShowLog");}}

Manifest.xml文件中声明<service android:name=".BindService" />

界面添加启动停止按钮:

<Buttonandroid:id="@+id/btnStartBindService"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="开始BindService" ></Button><Buttonandroid:id="@+id/btnStopBindService"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="结束BindService" ></Button>

AndroidServiceActivity绑定方法,Context.BIND_AUTO_CREATE表明只要绑定存在,就自动建立Service;同时也告知Android系统,这个Service的重要程度与调用者相同,除非考虑终止调用者,否则不要关闭这个Service。

如果service没被创建,那么调用一次onCreate(),然后调用onBind(),多次绑定时,不会多次调用onBind()。

通过unbindService()函数取消绑定Servcie时,onUnbind()函数将被调用, 
如果onUnbind()函数的返回true,则表示在调用者绑定新服务时, 
onRebind()函数将被调用

取消绑定仅需要使用unbindService()方法,并将ServiceConnnection传递给unbindService()方法需注意的是,unbindService()方法成功后,系统并不会调用onServiceDisconnected(),因为onServiceDisconnected()仅在意外断开绑定时才被调用

当bindService后,不能stopService,需要通过unBindService()来解除绑定

startService()后,不可以通过unBindService()来销毁service

private boolean isConn = false;//用来标志服务是否绑定private OnClickListener listener = new OnClickListener() {@Overridepublic void onClick(View v) {Intent intentBind = new Intent(AndroidServiceActivity.this, BindService.class);switch (v.getId()) {case R.id.btnStartBindService:bindService(intentBind, conn, Context.BIND_AUTO_CREATE);break;case R.id.btnStopBindService:if (isConn) {unbindService(conn); //不可以多次调用isConn=false;}break;}}};

声明conn,用来连接服务,调用服务的方法。

private ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {isConn=false;}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {BindServiceX bindServiceX = (BindServiceX) service;BindService bindService = bindServiceX.getBindService();bindService.ShowLog();isConn=true;}};

bindService()目的是回调onBind()方法,它的作用是在Service和调用者之间建立一个桥梁,并不负责更多的工作(例如一个Service需要连接服务器的操作),一般使用bindService来绑定到一个现有的Service(即通过StartService启动的服务),Activity 与 Service传递数据和调用接口。

以上两种使用方法并不是完全独立的,在某些情况下可以混合使用以MP3播放器为例,在后台的工作的Service通过Context.startService()启动某个特定音乐播放,但在播放过程中如果用户需要暂停音乐播放,则需要通过Context.bindService()获取服务链接和Service对象,进而通过调用Service的对象中的函数,暂停音乐播放过程,并保存相关信息。在这种情况下,如果调用Context.stopService()并不能够停止Service,需要在所有的服务链接关闭后,Service才能够真正的停止

Android中Services简析相关推荐

  1. Android 启动过程简析

    首先我们先来看android构架图: android系统是构建在linux系统上面的. 所以android设备启动经历3个过程. Boot Loader,Linux Kernel & Andr ...

  2. Android Telephony框架结构简析

    Android Telephony涉及的框架结构如图1所示. 图1  Android Telephony框架结构 通过图1可以发现Android Telephony框架结构的一些规律,具体如下. An ...

  3. Qualcomm Android camera 架构简析及如何debug

    一. Camera模组(CCM)介绍: CCM一般包含四大件: 镜头(lens).传感器(sensor).软板(FPC).图像处理芯片(DSP):     Camera的成像原理可以简单概括如下: 1 ...

  4. android中的多渠道打包,Android 多渠道打包简析

    前言 为了更好的统计每个来源的下载量,当我们项目打包的时候,需要打出不同渠道的包.如何打多渠道包?新一代构建工具gradle,其中的一大优势就是支持多渠道,多Apk打包. Gradle的基础概念 fl ...

  5. Android 启动过程简析(一)之 init 进程

    问题 在进入到 Android 启动过程之前先让我们思考以下几个问题 Android 系统的启动过程是怎样的? init .zygote 进程是什么?在系统启动的过程中各自发挥了什么作用? AMS.P ...

  6. android uboot启动过程,Android启动流程简析(一)

    最近一时兴起,想对Android的启动流程进行一次分析,经过一番整理,从以下几个方面进行总结,代码部分只讨论思路,不论细节. Android架构介绍 Android启动概述 BootLoader介绍 ...

  7. 坑爹的属性,android:descendantFocusability用法简析

    开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承 BaseAdapter,在adapter中按照需求进行编写,问题就出现 ...

  8. android:descendantFocusability用法简析

    开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了 ...

  9. Android 五大布局简析

    Android对用五大布局对象,它们分别是FrameLayout(框架布局),LinearLayout (线性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局) ...

最新文章

  1. 面了大厂的 Python 岗后,炸了!
  2. 【动态规划专题】数字三角形模型
  3. R语言seq函数生成数据序列实战
  4. 深度|人工智能赋能“新基建”产业的四方面及建议
  5. 最短编辑距离 python_最短编辑距离算法实现
  6. boost::gil模块数字扩展中的 resize_view() 示例
  7. 随手记录自动化常用的一些事情
  8. 美国大学计算机专业排名2014,2014年美国大学本科计算机专业排名
  9. gpu超算算法_2018电磁仿真(HFSS、CST、FEKO)单机集群并行计算特点分析与完美解决方案...
  10. win10开机密码忘记怎么办|win10登陆密码忘记解决方法
  11. G - Nightmare Ⅱ (双向BFS)
  12. 润物细无声之千分之一
  13. #私藏项目实操分享#Python爬虫实战,requests+xpath模块,Python实现爬取豆瓣影评
  14. python爬虫使用正则爬取网站
  15. NTP服务端和客户端的部署——Chrony
  16. privat,pubic的区别
  17. Java把一个大集合拆分成多个小集合,可以利用多线程提升并发处理效率
  18. Arduino开发实例-Lora 数据发送与接收
  19. Failed to create the part's controls
  20. Android 完整的自定义View

热门文章

  1. MySQL数据库常用的操作命令(二)
  2. 计算机操作系统模拟试题,最新考研计算机-操作系统模拟试题.doc
  3. python设计模式15-解释器模式
  4. 图像目标检测(Object Detection)原理与实现(三)
  5. 我用休眠做并发控制,搞垮了下游服务
  6. Golang 连接池的几种实现案例
  7. java计算器如何实现运算_用java编写了一个模拟计算器的界面设计,怎么实现运算功能呢...
  8. Redis:缓存问题之数据不一致(更新数据库时 主动更新)
  9. 如何在IDEA中创建并部署JavaWeb程序
  10. 如何关闭kafka的控制台日志