文章目录

  • 服务概述
  • 服务的两种启动方式
  • 服务的生命周期
  • startService
    • startService实例1
    • startService实例---电话监听器
    • startService实例---计时器
  • bindService
    • bindService实例---本地人员查询系统

服务概述

服务Serivce是Android系统中4大组件之一,有以下特点

  1. 后台运行
  2. 没有界面
  3. 服务无法自己启动
  4. 单例模式(一个服务在系统中只能启动一次)

基本使用步骤:

  1. 继承自Service
  2. 在清单文件中使用节点配置
  3. 启动服务

服务的两种启动方式

服务有两种启动方式

  1. startService方式

    • 该方法启动的服务所在的进程属于服务进程
    • Activity一旦启动服务,服务就跟Activity无关
  2. bindService方式

    • 该方法启动的服务所在进程不属于服务进程
    • Activity与服务建立连接,Activity退出,服务也退出

服务的生命周期

如果Service还没有运行,则Android先调用onCreate()方法,然后调用onStartCommad(),如果Service已经运行,则只调用onStartCommad()方法,所以一个Service的onStartCommad方法可能会调用多次

startService

startService实例1

xml界面代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn1"android:onClick="btnStart1"android:text="start启动服务"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn2"android:onClick="btnStop1"android:text="start关闭服务"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>

新建两个按钮,并创建onClick事件

然后新建一个服务

   @Overridepublic void onCreate() {super.onCreate();Log.d("GuiShou","MyService onCreate");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d("GuiShou","MyService onStartCommand");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();Log.d("GuiShou","MyService onDestroy");}

重写onCreate onStartCommand和onDestroy三个方法

 public void btnStart1(View view) {//创建IntentIntent intent=new Intent();//设置信息intent.setClass(this,MyService.class);//启动服务startService(intent);}public void btnStop1(View view) {//创建IntentIntent intent=new Intent();//设置信息intent.setClass(this,MyService.class);//关闭服务stopService(intent);}

最后完成创建服务和关闭服务的代码。

实际效果如图

点击启动服务,会调用onCreate和onStartCommand方法

再次点击启动服务,会调用onStartCommand方法

点击关闭服务,则调用onDestroy方法

startService实例—电话监听器

原理:在创建服务时获取电话管理器,注册监听器监听电话状态。这里基于上面的代码来完成这个实例。

  public class MyPhoneListener extends PhoneStateListener{@Overridepublic void onCallStateChanged(int state, String incomingNumber) {super.onCallStateChanged(state, incomingNumber);switch (state){case TelephonyManager.CALL_STATE_IDLE:Log.d("GuiShou","MyService 电话空闲");break;case TelephonyManager.CALL_STATE_OFFHOOK:Log.d("GuiShou","MyService 电话接听");break;case TelephonyManager.CALL_STATE_RINGING:Log.d("GuiShou","MyService 电话响铃");break;}}}

首先编写一个自己的电话监听类

 private TelephonyManager mTelephonyManager;private MyPhoneListener mMyPhoneListener;

接着定义两个成员变量

@Overridepublic void onCreate() {super.onCreate();Log.d("GuiShou","MyService onCreate");//获取电话管理器mTelephonyManager=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);//创建监听器mMyPhoneListener=new MyPhoneListener();//开始监听打电话状态mTelephonyManager.listen(mMyPhoneListener,PhoneStateListener.LISTEN_CALL_STATE);}

重写onCreate方法,开始监听电话状态

 @Overridepublic void onDestroy() {super.onDestroy();Log.d("GuiShou","MyService onDestroy");//取消监听mTelephonyManager.listen(mMyPhoneListener,PhoneStateListener.LISTEN_NONE);}

然后在onDestroy方法中取消监听

<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

然后在清单文件中添加读取电话状态的权限

startService实例—计时器

原理:在创建服务时在onCreate方法中启动定时器,定时发送广播。在创建Activity时注册广播接收者,接收时间广播,更新控件

首先新建一个服务,命名为TimerService

private Timer mTimer;
private int mCount=0;
private String mShouText="当前计时:0";

创建三个变量

@Overridepublic void onCreate() {super.onCreate();//创建定时器mTimer=new Timer();//创建定时器任务TimerTask timerTask=new TimerTask() {@Overridepublic void run() {mCount++;Log.d("GuiShou",mShouText+mCount);}};//给定时器指定定时器任务mTimer.schedule(timerTask,0,1000);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {mCount=0;   //重置return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();//取消定时器if (mTimer!=null){mTimer.cancel();mTimer=null;}}

然后完成onCreate onStartCommand和onDestroy方法

  <Buttonandroid:id="@+id/btn3"android:onClick="btnStart2"android:text="start启动服务-计时器"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn4"android:onClick="btnStop2"android:text="start关闭服务-计时器"android:layout_width="match_parent"android:layout_height="wrap_content" />

在界面文件中新增两个按钮,并添加onClick方法

  public void btnStart2(View view) {//创建IntentIntent intent=new Intent();//设置信息intent.setClass(this,TimerService.class);//启动服务startService(intent);}public void btnStop2(View view) {//创建IntentIntent intent=new Intent();//设置信息intent.setClass(this,TimerService.class);//关闭服务stopService(intent);}

启动服务和关闭服务代码和之前相同,只需要修改服务名

实际效果如图:

启动服务后,定时器开始自动计时

bindService

绑定方式(bindService)

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

bindService实例—本地人员查询系统

首先编写界面代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:orientation="vertical"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn1"android:onClick="btnBind"android:text="绑定服务"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn2"android:onClick="btnUnBind"android:text="解绑服务"android:layout_width="match_parent"android:layout_height="wrap_content" /><EditTextandroid:id="@+id/edit_query"android:hint="请在此输入ID"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn3"android:onClick="btnQuery"android:text="查询"android:layout_width="match_parent"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/tv1"android:text="当前数据:"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>

新建一个服务,命名为BindService

新建一个接口,命名为IPersonListener

public interface IPersonListener {String queryNameById(int id);
}

在接口中声明queryNameById方法

String names[]={"齐天大圣","猪八戒","沙和尚","白龙马"};public class MyBinder extends Binder implements IPersonListener{@Overridepublic String queryNameById(int id) {if (id<0&&id>3){return "唐僧";}return names[id];}}

在服务中编写一个内部类,实现IPersonListener接口,完成查询方法

    public MyBinder mMyBinder;@Overridepublic IBinder onBind(Intent intent) {Log.d("GuiShou","MyBindService::onBind");// TODO: Return the communication channel to the service.return mMyBinder;}@Overridepublic void onCreate() {super.onCreate();mMyBinder=new MyBinder();Log.d("GuiShou","MyBindService::onCreate");}

然后定义类对象,在onCreate方法中新建对象,在onBind中返回对象

public class MyServiceConnection implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {}@Overridepublic void onServiceDisconnected(ComponentName componentName) {}}private MyServiceConnection mMyServiceConnection;

在MainActivity中创建一个内部类,并实现ServiceConnection接口;然后定义类对象

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mMyServiceConnection=new MyServiceConnection();}

并且在onCreate方法中对类对象进行初始化

public void btnBind(View view) {Intent intent=new Intent(this,BindService.class);bindService(intent,mMyServiceConnection,Context.BIND_AUTO_CREATE);}public void btnUnBind(View view) {Intent intent=new Intent(this,BindService.class);unbindService(mMyServiceConnection);stopService(intent);}

完成按钮响应事件的绑定和解绑服务代码

private BindService.MyBinder mMyBinder;

然后定义一个MyBinder对象

 public class MyServiceConnection implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {Log.d("GuiShou","MyBindService::onServiceConnected");mMyBinder= (BindService.MyBinder) iBinder;}

然后在onServiceConnected方法中去获取MyBinder的类对象

 public void btnQuery(View view) {EditText editText=findViewById(R.id.edit_query);String string=editText.getText().toString();int num=Integer.parseInt(string);if (mMyBinder!=null){String name=mMyBinder.queryNameById(num);TextView textView=findViewById(R.id.tv1);textView.setText(name);}}

最后完成查询函数。实际效果如图

008 Android之Service相关推荐

  1. Android中service应用

    Android开发中,当需要创建在后台运行的程序的时候,就要使用到Service.Service 可以分为有无限生命和有限生命两种.特别需要注意的是Service跟Activities是不同的(简单来 ...

  2. android 47 service绑定

    如果一个service已经启动了,activity和service绑定了在解除邦定,则这个service不会销毁,因为这个service不是这个Activity创建的. service生命周期: Ac ...

  3. Android开发--Service和Activity通过广播传递消息

    Android的Service也运行在主线程,但是在服务里面是没法直接调用更改UI,如果需要服务传递消息给Activity,通过广播是其中的一种方法: 一.在服务里面发送广播 通过intent传送数据 ...

  4. android Hander Service 广播的综合使用案例

    android Hander  Service  广播的综合使用案例 原理:在主activity里启动一个服务,这个服务通过Handler每一秒发送一条广播,并在主activity里注册一个广播接受者 ...

  5. Android 通过Service单独进程模仿离线推送 Server Push

    2019独角兽企业重金招聘Python工程师标准>>> 概述: 首先简单阐述一下我对于消息推送的理解,这里拿QQ来举例吧,当我们手机端的QQ离线了,并且退出了QQ应用,但是这时候如果 ...

  6. Android之Service与IntentService的比较

    Android之Service与IntentService的比较  不知道大家有没有和我一样,以前做项目或者练习的时候一直都是用Service来处理后台耗时操作,却很少注意到还有个IntentServ ...

  7. Android 保持Service不被Kill掉的方法--双Service守护 Android实现双进程守护

    本文分为两个部分,第一部分为双Service守护,第二部分为双进程守护 第一部分: 一.Service简介:Java.lang.Object ↳Android.content.Context  ↳an ...

  8. Android之Service

    2019独角兽企业重金招聘Python工程师标准>>> 1.Service的种类   按运行地点分类: 类别 区别  优点 缺点   应用 本地服务(Local) 该服务依附在主进程 ...

  9. Android中Service的使用

    我个人的理解是:我们平时使用的android系统的app的后台应用,就是这个原理 可以利用Service实现程序在后台运行,依照这个原理,可以通过Service来实现关键代码的运行与实现. <一 ...

最新文章

  1. 项目Alpha冲刺 10
  2. Promise.allSettled
  3. Cubieboard2 debian
  4. springboot elasticsearch vue ik中文分词器 实现百度/京东全文搜索
  5. Backblaze发布2016年2季度硬盘可靠性报告
  6. ArcGIS 地表TIN面数据的符号化
  7. HTC全景视频,2D 3D视频播放器下载教程
  8. 泰坦尼克号沉没之谜,用数据还原真相——Titanic获救率分析(用pyecharts)
  9. 女程序员在互联网界到底有没有被歧视?
  10. 2021年中国5G手机发展现状及市场竞争格局分析:华为持续领跑国内5G手机市场[图]
  11. 《深入浅出WPF》系列视频(特辑)——MVVM入门与提高(难度300+)
  12. 微信小程序体验评分问题
  13. simulink【1】分段函数
  14. Mac不同应用之间切换使用不同输入法
  15. 复旦大学管理学院2017年考博(高级微观经济学+管理理论综合)真题,高微老师上课资料
  16. 再读《谁动了我的奶酪》
  17. 2020-12-18T16:51:56+08:00 时间转换方法
  18. 训练人工智能机器人的软实力
  19. Oracle Primavera P6软件项目进度评估与偏差控制
  20. 【转载】高效使用vim

热门文章

  1. ML之Hash_HamMingDistance:基于输入图片哈希化(均值哈希+差值哈希)即8*8个元素的单向vector利用汉明距离算法进行判别
  2. DL之DNN优化技术:利用Batch Normalization(简介、入门、使用)优化方法提高DNN模型的性能
  3. Centos7通过yum安装最新MySQL
  4. Python之PIL库的运用、GIF处理
  5. VS打开文件,解决方案资源管理器自动定位到文件位置
  6. 重构手法之简化函数调用【1】
  7. 10分钟开始.Net Core
  8. Lesson 02:变量、数据类型
  9. AC自动机-洛谷3121 [USACO15FEB]审查(黄金)Censoring (Gold)
  10. ---Mybatis3学习笔记(2)