008 Android之Service
文章目录
- 服务概述
- 服务的两种启动方式
- 服务的生命周期
- startService
- startService实例1
- startService实例---电话监听器
- startService实例---计时器
- bindService
- bindService实例---本地人员查询系统
服务概述
服务Serivce是Android系统中4大组件之一,有以下特点
- 后台运行
- 没有界面
- 服务无法自己启动
- 单例模式(一个服务在系统中只能启动一次)
基本使用步骤:
- 继承自Service
- 在清单文件中使用节点配置
- 启动服务
服务的两种启动方式
服务有两种启动方式
startService方式
- 该方法启动的服务所在的进程属于服务进程
- Activity一旦启动服务,服务就跟Activity无关
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相关推荐
- Android中service应用
Android开发中,当需要创建在后台运行的程序的时候,就要使用到Service.Service 可以分为有无限生命和有限生命两种.特别需要注意的是Service跟Activities是不同的(简单来 ...
- android 47 service绑定
如果一个service已经启动了,activity和service绑定了在解除邦定,则这个service不会销毁,因为这个service不是这个Activity创建的. service生命周期: Ac ...
- Android开发--Service和Activity通过广播传递消息
Android的Service也运行在主线程,但是在服务里面是没法直接调用更改UI,如果需要服务传递消息给Activity,通过广播是其中的一种方法: 一.在服务里面发送广播 通过intent传送数据 ...
- android Hander Service 广播的综合使用案例
android Hander Service 广播的综合使用案例 原理:在主activity里启动一个服务,这个服务通过Handler每一秒发送一条广播,并在主activity里注册一个广播接受者 ...
- Android 通过Service单独进程模仿离线推送 Server Push
2019独角兽企业重金招聘Python工程师标准>>> 概述: 首先简单阐述一下我对于消息推送的理解,这里拿QQ来举例吧,当我们手机端的QQ离线了,并且退出了QQ应用,但是这时候如果 ...
- Android之Service与IntentService的比较
Android之Service与IntentService的比较 不知道大家有没有和我一样,以前做项目或者练习的时候一直都是用Service来处理后台耗时操作,却很少注意到还有个IntentServ ...
- Android 保持Service不被Kill掉的方法--双Service守护 Android实现双进程守护
本文分为两个部分,第一部分为双Service守护,第二部分为双进程守护 第一部分: 一.Service简介:Java.lang.Object ↳Android.content.Context ↳an ...
- Android之Service
2019独角兽企业重金招聘Python工程师标准>>> 1.Service的种类 按运行地点分类: 类别 区别 优点 缺点 应用 本地服务(Local) 该服务依附在主进程 ...
- Android中Service的使用
我个人的理解是:我们平时使用的android系统的app的后台应用,就是这个原理 可以利用Service实现程序在后台运行,依照这个原理,可以通过Service来实现关键代码的运行与实现. <一 ...
最新文章
- 项目Alpha冲刺 10
- Promise.allSettled
- Cubieboard2 debian
- springboot elasticsearch vue ik中文分词器 实现百度/京东全文搜索
- Backblaze发布2016年2季度硬盘可靠性报告
- ArcGIS 地表TIN面数据的符号化
- HTC全景视频,2D 3D视频播放器下载教程
- 泰坦尼克号沉没之谜,用数据还原真相——Titanic获救率分析(用pyecharts)
- 女程序员在互联网界到底有没有被歧视?
- 2021年中国5G手机发展现状及市场竞争格局分析:华为持续领跑国内5G手机市场[图]
- 《深入浅出WPF》系列视频(特辑)——MVVM入门与提高(难度300+)
- 微信小程序体验评分问题
- simulink【1】分段函数
- Mac不同应用之间切换使用不同输入法
- 复旦大学管理学院2017年考博(高级微观经济学+管理理论综合)真题,高微老师上课资料
- 再读《谁动了我的奶酪》
- 2020-12-18T16:51:56+08:00 时间转换方法
- 训练人工智能机器人的软实力
- Oracle Primavera P6软件项目进度评估与偏差控制
- 【转载】高效使用vim
热门文章
- ML之Hash_HamMingDistance:基于输入图片哈希化(均值哈希+差值哈希)即8*8个元素的单向vector利用汉明距离算法进行判别
- DL之DNN优化技术:利用Batch Normalization(简介、入门、使用)优化方法提高DNN模型的性能
- Centos7通过yum安装最新MySQL
- Python之PIL库的运用、GIF处理
- VS打开文件,解决方案资源管理器自动定位到文件位置
- 重构手法之简化函数调用【1】
- 10分钟开始.Net Core
- Lesson 02:变量、数据类型
- AC自动机-洛谷3121 [USACO15FEB]审查(黄金)Censoring (Gold)
- ---Mybatis3学习笔记(2)