Android四大组件-服务
Android服务
android 的服务有点类似windows的服务,没有界面,在后台长时间运行,如果我们这种需求的话我们就可以使用服务来实现。
服务的典型应用场景: 播放音乐,下载等,如果要在一个广播接收者中执行一些耗时的操作,可以将此操作转交给服务来执行。
服务也有自己的生命周期,但是要是相对Activity要少了许多。
服务的生命周期
图片来自于官方文档

使用服务
如果你想要使用服务,那么必须要有一个来继承【Service 】类,并且在清单文件中配置他。
配置服务:在清单文件中对服务进行配置
<!--配置一个服务,与Activity的配置基本相同,都可以具有Intent-Filter-->
<service android:name=".MyService">
<intent-filter>
<action android:name="MyAction" />
</intent-filter>
</service>
建立服务类: 新建一个类继承自Service
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
startService 的方式开始服务
- 一旦开启就会长久的存在,就算是没有界面了那么也会在后台运行,没有界面的时候就会是一个服务进程,如果没有特殊的情况下次进程是不会被结束的,除非 用户手动停止或者调用onStop() 方法。
- 可以多次开启,如果点击按钮开启服务多次点击按钮的话就会执行多次的onStartCommand方法,但是onCreate方法仅仅执行一次。
- 用户可以再设置中查看通过此方式开启的服务
public class MainActivity extends AppCompatActivity {
private Intent intentService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentService = new Intent(this, PhoneListenerService.class);
}
//开启个服务
public void click(View v) {
this.startService(this.intentService);
}
//停止服务
public void click2(View v) {
this.stopService(this.intentService);
}
bindService 的方式开启服务
- 一般在Activity中开启,如果activity销毁了那么通过此方式绑定服务也会跟着销毁在activity销毁之前要先解绑服务。
- 这种方式开启的服务用户在设置中是无法看到的。
public class Main1Activity extends AppCompatActivity {
private Intent serviceIntent;
private MyServiceConnection conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
serviceIntent = new Intent(this, MyService.class);
conn = new MyServiceConnection();
}
//绑定一个服务
public void click3(View v) {
this.bindService(this.serviceIntent, this.conn, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(this.conn);
}
}
class MyServiceConnection implements ServiceConnection {
//当服务连接成功后会调用此方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LogHelper.Logi("连接到服务");
}
//当失去连接的时候回调用此方法
@Override
public void onServiceDisconnected(ComponentName name) {
LogHelper.Logi("取消连接");
}
}
为什么要有Bind方式开启服务
下面我们有这么个需求,我要调用服务里面的方法。
正常的调用方式
服务代码
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
LogHelper.LogI("onBind");
return null;
}
@Override
public void onCreate() {
super.onCreate();
LogHelper.LogI("onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogHelper.LogI("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
LogHelper.LogI("onDestory");
}
//我想在activity中调用的方法
public void showToast() {
Toast.makeText(this.getApplicationContext(), "Toast", Toast.LENGTH_SHORT).show();
}
}
调用代码
public class Main1Activity extends AppCompatActivity {
private Intent serviceIntent;
private MyServiceConnection conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
serviceIntent = new Intent(this, MyService.class);
conn = new MyServiceConnection();
//绑定服务
bindService(this.serviceIntent, conn, BIND_AUTO_CREATE);
}
/*
* 直接通过new出来对象的方式来调用服务中的方法
* */
public void click(View v) {
new MyService().showToast();
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(this.conn);
}
}
class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
总结
这样的方式调用service中的方法,就会直接挂掉.....,因为如果这样直接new出来的服务类的话,系统就会将他当成一个普通的java类来处理,在普通的java类中是不能获得上下文对象的,所以就不能弹出吐司,如果没有涉及的上下文的方法,那么这样是可以执行的。
解决办法
通过一个中间人来调用我们想要调用的方法
服务端代码
public class MyService extends Service {
/*
* 通过bind方式开启服务 会执行onCreate()->onBind()方法
* 此方法返回我们需要的中间人,来调用服务中的方法
* */
@Nullable
@Override
public IBinder onBind(Intent intent) {
LogHelper.LogI("onBind");
return new MyBinder();
}
@Override
public void onCreate() {
super.onCreate();
LogHelper.LogI("onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogHelper.LogI("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
LogHelper.LogI("onDestory");
}
//我们想要调用的方法
public void showToast() {
Toast.makeText(this.getApplicationContext(), "Toast", Toast.LENGTH_SHORT).show();
}
/*
* 定义中间人
* 间接的调用我们想要调用的方法
* */
public class MyBinder extends Binder {
public void callShowToast() {
showToast();
}
}
}
Activity代码
public class Main1Activity extends AppCompatActivity {
private Intent serviceIntent;
private MyServiceConnection conn;
private MyService.MyBinder callBinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
serviceIntent = new Intent(this, MyService.class);
conn = new MyServiceConnection();
//绑定服务
bindService(this.serviceIntent, conn, BIND_AUTO_CREATE);
}
/*
* 通过定义的中间人来调用方法
* */
public void click(View v) {
this.callBinder.callShowToast();
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(this.conn);
}
public class MyServiceConnection implements ServiceConnection {
/*
* 当连接到服务的时候就会执行此方法,在这个方法拿到我们的中间人用来调用我们想要调用的方法
* service参数就是我们想要的中间人
* */
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
callBinder = (MyService.MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
混合方式绑定服务
现在有一种情况,如果我要做一个音乐盒的功能那么我必须在所有界面都退出了还能播放那么这时候,我们一定是要有一个startService方式开启的服务来一直播放音乐, 但是我得需要调用服务中的方法来控制音乐的播放和暂停等,这就需要混合方式开启服务了。
混合方式开启服务的步骤
- startService()
- bindService()
- unbiasedServices()
- stopService()
Demo 音乐播放器 案例
服务的代码
public class MusicService extends Service {
private boolean isPlay = true;
private boolean isDestroy = false;
public MusicService() {
}
@Override
public IBinder onBind(Intent intent) {
LogHelper.LogI("onBind");
return new MyBinder();
}
@Override
public void onCreate() {
LogHelper.LogI("onCreate!");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogHelper.LogI("onStart");
playMusic();
return super.onStartCommand(intent, flags, startId);
}
//在服务被销毁的时候,结束线程
@Override
public void onDestroy() {
LogHelper.LogI("onDestory");
this.isDestroy = true;
super.onDestroy();
}
//开启线程不停的播放音乐
public void playMusic() {
new Thread(new Runnable() {
@Override
public void run() {
while (!isDestroy)
if (isPlay) {
LogHelper.LogI("Play Music!");
SystemClock.sleep(1000);
}
}
}).start();
}
//暂停音乐播放
public void stopMusic() {
this.isPlay = false;
LogHelper.LogI("暂停播放音乐!");
}
//继续播放音乐
public void continueMusic() {
this.isPlay = true;
LogHelper.LogI("继续播放音乐!");
}
//用来调用服务的方法的中间人
private class MyBinder extends Binder implements IMusicControlAble {
@Override
public void callStopMusic() {
stopMusic();
}
@Override
public void callContinueMusic() {
continueMusic();
}
}
}
IMusicControlAble接口代码
public interface IMusicControlAble {
//暂停音乐播放
public void callStopMusic();
//继续播放音乐
public void callContinueMusic();
}
MainActivity的代码
public class Main1Activity extends AppCompatActivity {
private Intent intentMusicService;
private MyServiceConnection connMusicService;
private IMusicControlAble musicControl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
intentMusicService = new Intent(this, MusicService.class);
connMusicService = new MyServiceConnection();
this.bindService(this.intentMusicService, this.connMusicService, BIND_AUTO_CREATE);
this.startService(this.intentMusicService);
}
public void click(View v) {
Button btn = (Button) v;
switch (btn.getText().toString()) {
case "暂停":
this.musicControl.callStopMusic();
btn.setText("播放");
break;
case "播放":
this.musicControl.callContinueMusic();
btn.setText("暂停");
break;
}
}
//接触对服务的绑定
@Override
protected void onDestroy() {
this.unbindService(this.connMusicService);
super.onDestroy();
}
public class MyServiceConnection implements ServiceConnection {
//拿到用来控制音乐状态的接口
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
musicControl = (IMusicControlAble) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
Android四大组件-服务的更多相关文章
- 入职小白随笔之Android四大组件——服务(Service)
Service Android多线程编程 当我们在程序中执行一些耗时操作时,比如发起一条网络请求,考虑到网速等原因,服务器未必会立刻响应我们的请求,此时我们就需要将这些操作放在子线程中去运行,以防止主 ...
- Android四大组件--服务(Service)
1. startService和bindService的区别 1. startService: 生命周期: onCreate---onStartCommand---onDestory 与服务的通讯: ...
- Android四大组件之一“广播”
前言 Android四大组件重要性已经不言而喻了,今天谈谈的是Android中的广播机制.在我们上学的时候,每个班级的教室里都会装有一个喇叭,这些喇叭都是接入到学校的广播室的,一旦有什么重要的通知,就 ...
- Android 四大组件 与 MVC 架构模式
作为一个刚从JAVA转过来的Android程序员总会思考android MVC是什么样的? 首先,我们必须得说Android追寻着MVC架构,那就得先说一下MVC是个啥东西! 总体而来说MVC不能说是 ...
- android四大组件(简单总结)
activity 一个Activity通常就是一个单独的屏幕(窗口) Activity之间通过Intent进行通信 android应用中每一个Activity都必须要在AndroidManifest. ...
- Android 四大组件之再论service
service常见的有2种方式,本地service以及remote service. 这2种的生命周期,同activity的通信方式等,都不相同. 关于这2种service如何使用,这里不做介绍,只是 ...
- Android四大组件及activity的四大启动模式
Android四大组件 1. 广播接收者的两种类型: (1)系统广播接收者,就是继承BroadcastReceiver这个类,然后还要在清单文件中注册,注册之后给他一个action.当系统发生了这个a ...
- Android成长日记-Android四大组件之Service组件的学习
1.什么是Service? Service是Android四大组件中与Activity最相似的组件,它们都代表可执行的程序,Service与Activity的区别在于:Service一直在后台运行,它 ...
- Android四大组件之Service
Android四大组件之Service Android支持服务的概念,服务是在后台运行的组件,没有用户界面,Android服务可用有与活动独立的生命周期.Android支持两种类型的服务: 本地服务: ...
随机推荐
- c++刷题(21/100)树的打印、矩阵覆盖和括号生成
题目一:把二叉树打印成多行 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 思路:一开始以为2维的vector可以直接访问,但是试了是不行,会报错,vector在有值之前不能直接访问 ...
- Task多线程进行多进程
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using Sys ...
- C基础 - 终结 Size Balanced Tree
引言 - 初识 Size Balanced Tree 最近在抽细碎的时间看和学习 random 的 randnet 小型网络库. iamrandom/randnet - https://github. ...
- vue实现结算淘宝购物车效果
实现单选时的价格,全选时价格 单选效果图 全选效果图 html <template> <!-- 淘宝结算购物车 --> <div class="settleme ...
- Spring入门实例
Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. 控制反转:应 ...
- 【Android开发】之Fragment开发1
一直知道Fragment很强大,但是一直都没有去学习,现在有些空闲的时间,所以就去学习了一下Fragment的简单入门.我也会把自己的学习过程写下来,如果有什么不足的地方希望大牛指正,共同进步! 一. ...
- go语言版本变化
The Go Project Go is an open source project developed by a team at Google and many contributors ...
- Unix IPC之Posix消息队列(1)
部分参考:http://www.cnblogs.com/Anker/archive/2013/01/04/2843832.html IPC对象的持续性:http://book.51cto.com/ar ...
- Filebeat配置paths里,不支持递归所有子目录
这个知识点要牢记哟,不然,牛B吹大了,收不回哈. 官方文档为证: Currently it is not possible to recursively fetch all files in all ...
- VMware虚拟机Mac OS X无法调整扩展硬盘大小的解决方案
使用VMware虚拟机搭建的MacOSX,在10.10以上可能会出现无法扩充磁盘大小的问题. 因为很多朋友在初次安装MacOSX的时候都默认选择40G的磁盘大小,结果用了没两天之后就发现磁盘不够用了. ...