定义和用途

Service是Android的四大组件之一,一直在后台运行,没有用户界面。Service组件通常用于为其他组件提供后台服务或者监控其他组件的运行状态,例如播放音乐、记录地理位置,监听用户操作等等。它的优先级要高于Activity。它运行在主线程中,所以不能一用它来做一些耗时的请求或者操作。

Service的分类

1. 本地服务(Local Service):主要用于程序内部

2. 远程服务(Remote Service):用于Android系统内部的应用程序之间

定义Service的步骤

开发Service和定义一个Activity一样,只需两个步骤

1. 定义一个继承Service的子类

2. 在AndroidManiFest.xml中注册该Service

Service的启动方式

startService方式启动

MainActivity.java

package cn.lixyz.servicedemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View; public class MainActivity extends Activity { Intent intent; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); findViewById(R.id.btnStartService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, MyStartService.class);
startService(intent);
}
}); findViewById(R.id.btnStopService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
});
}
}

activity_layout.xml

<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="cn.lixyz.servicedemo.MainActivity"> <Button
android:id="@+id/btnStartService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="启动服务" /> <Button
android:id="@+id/btnStopService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭服务" /> </LinearLayout>

MyStartService.java

package cn.lixyz.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log; public class MyStartService extends Service { int i = 1; @Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public void onCreate() {
Log.d("TEST",i++ + ".onCreate方法执行。。。");
super.onCreate();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TEST",i++ + ".onStartCommand。。。");
return super.onStartCommand(intent, flags, startId);
} @Override
public boolean onUnbind(Intent intent) {
Log.d("TEST",i++ + ".onUnbind。。。");
return super.onUnbind(intent);
} @Override
public void onDestroy() {
Log.d("TEST",i++ + ".onDestroy。。。");
super.onDestroy();
}
}

AndroidManiFest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.lixyz.servicedemo" > <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <service
android:name=".MyStartService"
android:enabled="true"
android:exported="true" >
</service>
<service
android:name=".MyBindService"
android:enabled="true"
android:exported="true" >
</service>
</application> </manifest>

连续点击三次启动服务按钮,再连续点击三次关闭服务按钮,Log如下

bindService方式启动

MainActivity.java

package cn.lixyz.servicedemo;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View; public class MainActivity extends Activity implements ServiceConnection { Intent intent ; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); findViewById(R.id.btnStartService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, MyBindService.class);
startService(intent);
}
}); findViewById(R.id.btnStopService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
}); findViewById(R.id.btnBindService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, MyBindService.class);
bindService(intent, MainActivity.this, Service.BIND_AUTO_CREATE);
}
}); findViewById(R.id.btnUnbindService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(MainActivity.this);
}
});
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("TEST","onServiceConnected方法执行了。。。。");
} @Override
public void onServiceDisconnected(ComponentName name) {
Log.d("TEST","onServiceDisconnected。。。。");
}
}

activity_layout.xml

<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="cn.lixyz.servicedemo.MainActivity"> <Button
android:id="@+id/btnStartService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="启动服务" /> <Button
android:id="@+id/btnStopService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭服务" /> <Button
android:id="@+id/btnBindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务" /> <Button
android:id="@+id/btnUnbindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消绑定服务" /> </LinearLayout>

MyBindService.java

package cn.lixyz.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; public class MyBindService extends Service { int i = 1; public MyBindService() {
} @Override
public IBinder onBind(Intent intent) {
return new Binder();
} @Override
public void onCreate() {
Log.d("TEST", i++ + ".onCreate方法执行。。。");
super.onCreate();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TEST", i++ + ".onStartCommand。。。");
return super.onStartCommand(intent, flags, startId);
} @Override
public boolean onUnbind(Intent intent) {
Log.d("TEST", i++ + ".onUnbind。。。");
return super.onUnbind(intent);
} @Override
public void onDestroy() {
Log.d("TEST", i++ + ".onDestroy。。。");
super.onDestroy();
} }

AndroidManiFest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.lixyz.servicedemo" > <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <service
android:name=".MyStartService"
android:enabled="true"
android:exported="true" >
</service>
<service
android:name=".MyBindService"
android:enabled="true"
android:exported="true" >
</service>
</application> </manifest>

运行结果:

Service的生命周期

从上面的运行结果可以看出Service的生命周期

1. 被启动的服务的声明周期:如果一个Service被某个Activity调用Context.startService()方法启动,那么不管是否有Activity使用bindService()绑定或者unbindService接触绑定到该Service,该Service都会在后台运行。如果一个Service被startService()方法多次启动,那么onCreate方法只调用一次,onstart()方法将会被调用多次,并且系统只会创建Service的一个实例(因此只需要调用一次stopService()),该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,知道被调用stopService(),或者自身的stopSelf()。

2. 被绑定的服务的生命周期:如果一个Service被某个Activity调用Content.bindService()方法绑定,不管调用bindService()调用几次,onCreate()方法都只会调用一次,同时onStart()方法始终不会被调用,当建立连接之后,Service将会一直运行,除非调用Context.unbindService()断开链接或者之前调用bindService的Context不存在了(如Activity被finish掉了),系统将会自动停止Service,对应onDestroy()将被调用。

3. 被启动又被绑定的服务的生命周期:如果一个Service又被启动又被绑定,则该Service将会一直在后台运行,并且不管如何调用,onCreate()始终只会调用一次,对应startService() 调用多少次,Service的onStart()便会调用多少次,调用unbindService将不会停止Service,必须调用stopService或者Service的stopSelf来停止服务。

4. 当服务停止时清楚服务:当一个Service被终止(①调用stopService ②调用stopSelf ③不再有绑定的连接(没有被启动时)),onDestroy()方法将会被调用,在这里你应当做一些清除工作,如停止在Service中创建并运行线程。

Service中的数据传递

startService并传递数据

MainActivity.java

package cn.lixyz.servicedemo;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.EditText; public class MainActivity extends Activity implements ServiceConnection { Intent intent ; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); findViewById(R.id.btnStartService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, MyStartService.class);
String str = ((EditText)findViewById(R.id.et_input)).getText().toString();
intent.putExtra("data",str);
startService(intent);
}
}); findViewById(R.id.btnStopService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
}); findViewById(R.id.btnBindService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, MyBindService.class);
bindService(intent, MainActivity.this, Service.BIND_AUTO_CREATE);
}
}); findViewById(R.id.btnUnbindService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(MainActivity.this);
}
});
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("TEST","onServiceConnected方法执行了。。。。");
} @Override
public void onServiceDisconnected(ComponentName name) {
Log.d("TEST","onServiceDisconnected。。。。");
}
}

activity_layout.xml

<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="cn.lixyz.servicedemo.MainActivity"> <EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入要传入的内容"/> <Button
android:id="@+id/btnStartService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="启动服务" /> <Button
android:id="@+id/btnStopService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭服务" /> <Button
android:id="@+id/btnBindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务" /> <Button
android:id="@+id/btnUnbindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消绑定服务" /> </LinearLayout>

MyStartService.java

package cn.lixyz.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log; import java.io.FileDescriptor; public class MyStartService extends Service { String str; @Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public void onCreate() {
super.onCreate();
new Thread() {
@Override
public void run() {
super.run();
str = "预定内容";
for (int i = 0; i <= 50; i++) {
Log.d("TEST", str);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
str = intent.getStringExtra("data");
return super.onStartCommand(intent, flags, startId);
} @Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
} @Override
public void onDestroy() {
super.onDestroy();
}
}

AndroidManiFest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.lixyz.servicedemo" > <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <service
android:name=".MyStartService"
android:enabled="true"
android:exported="true" >
</service>
<service
android:name=".MyBindService"
android:enabled="true"
android:exported="true" >
</service>
</application> </manifest>

运行结果:

bindService并传递数据

MainActivity.java

package cn.lixyz.servicedemo;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.EditText; public class MainActivity extends Activity implements ServiceConnection { Intent intent ;
MyBindService.Binder binder; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); findViewById(R.id.btnStartService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, MyStartService.class);
startService(intent);
}
}); findViewById(R.id.btnStopService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
}); findViewById(R.id.btnBindService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent = new Intent(MainActivity.this, MyBindService.class);
bindService(intent, MainActivity.this, Service.BIND_AUTO_CREATE);
}
}); findViewById(R.id.btnUnbindService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(MainActivity.this);
}
}); findViewById(R.id.btnSyncService).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String str = ((EditText) findViewById(R.id.et_input)).getText().toString();
binder.setString(str);
}
});
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("TEST","onServiceConnected方法执行了。。。。");
binder = (MyBindService.Binder) service;
} @Override
public void onServiceDisconnected(ComponentName name) {
Log.d("TEST","onServiceDisconnected。。。。");
}
}

activity_layout.xml

<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="cn.lixyz.servicedemo.MainActivity"> <EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入要传入的内容"/> <Button
android:id="@+id/btnStartService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="启动服务" /> <Button
android:id="@+id/btnStopService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭服务" /> <Button
android:id="@+id/btnBindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务" /> <Button
android:id="@+id/btnUnbindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消绑定服务" /> <Button
android:id="@+id/btnSyncService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="同步服务"/> </LinearLayout>

MyBindService.java

package cn.lixyz.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; public class MyBindService extends Service { String str = "默认信息"; public MyBindService() {
} @Override
public IBinder onBind(Intent intent) { return new Binder();
} public class Binder extends android.os.Binder{
public void setString(String str){
MyBindService.this.str = str;
}
} @Override
public void onCreate() {
Log.d("TEST", ".onCreate方法执行。。。"); new Thread(){
@Override
public void run() {
super.run(); for (int i = 0;i<80;i++){
Log.d("TEST",i + str);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
}.start(); super.onCreate();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TEST", ".onStartCommand方法执行。。。"); return super.onStartCommand(intent, flags, startId);
} @Override
public boolean onUnbind(Intent intent) {
Log.d("TEST", ".onUnbind方法执行。。。");
return super.onUnbind(intent);
} @Override
public void onDestroy() {
Log.d("TEST", ".onDestroy方法执行。。。");
super.onDestroy();
} }

AndroidManiFest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.lixyz.servicedemo" > <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <service
android:name=".MyStartService"
android:enabled="true"
android:exported="true" >
</service>
<service
android:name=".MyBindService"
android:enabled="true"
android:exported="true" >
</service>
</application> </manifest>

运行结果:

Android笔记(十七) Android中的Service的更多相关文章

  1. Android 笔记之 Android 系统架构

    Android笔记之Android系统架构 h2{ color: #4abcde; } a{ color: blue; text-decoration: none; } a:hover{ color: ...

  2. Android入门(十七)Android多线程

    原文链接:http://www.orlion.ga/670/ 一.在子线程中更新UI Android中不允许在子线程中更新UI,只能在主线程中更新,但是我们有时候必须在子线程中执行一些耗时的任务,然后 ...

  3. Android笔记: Android版本号

    由于有2套版本号 总是对应不准 记下来做过标记 Android 4.3 ----18 Android 4.2---17 Android 4.1---16 Android 4.0.3---15Andro ...

  4. Android笔记:java 中的数组

    在与嵌入式设备通讯的过程中使用的socket通讯 获取的字节流,通常转换为字节数组,需要根据协议将字节数组拆分.对于有规律的重复拆分可以使用,由于java中不能像c中直接进行内存操作例如使用struc ...

  5. Android笔记:java 中的枚举

    部分数据使用枚举比较方便,java中的enmu不如c#中使用方便 记录备忘 以c#中的代码为例 public enum PlayState { /// <summary> /// 关闭 / ...

  6. Android笔记之Fragment中创建ViewModel的正确方式

    之前一直都是这么写的 pageViewModel = ViewModelProviders.of(this).get(PageViewModel.class); //参数this是当前fragment ...

  7. Java学习笔记十七:Java中static使用方法

    Java中static使用方法 一:Java中的static使用之静态变量: 我们都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的 ...

  8. Android笔记:android的适配

    public int Dp2Px(Context context, float dp) { final float scale = context.getResources().getDisplayM ...

  9. Android笔记二十七.Service组件入门(一).什么是Service?

    转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.Service 1.Service简单介绍     Service为Android四大组件之中 ...

随机推荐

  1. 图片缩放——利用layui的滑块

    @layui官网文档.@参考博客 参考博客中能实现,但是效果差强人意,在前辈的基础上进行了改造,并支持了动态多图列表 <%@ page language="java" con ...

  2. Python - Django - ORM 聚合查询和分组查询

    models.py: from django.db import models # 出版社 class Publisher(models.Model): id = models.AutoField(p ...

  3. idea能用下划线替换红色报错吗?我色弱,用idea简直太痛苦了

    看看下图的idea,如果某个类的包路径没有引进来,使用颜色来提示,这对于色弱的程序员简直是一种折磨,有没有可以改成eclipse的那种报错提示方式? 个人感觉idea真的没有eclipse友好,也许是 ...

  4. LODOP中带caption的表格被关联并次页偏移测试

    ADD_PRINT_TABLE中的thead和tfoot可以每页输出,后面的打印项关联表格,可以紧跟着表格,实现在表格后面紧跟着输出内容的效果,表格可以自动分页,并总是跟在表格后面 ,在表格最后输出. ...

  5. 利用VisualSVN修改配置库名称

    相信大家都听说过SVN的大名,至于它的用途以及如何安装不在本文范围内,这里主要讲解如何利用VisualSVN来更改配置库的名称,前提是你的SVN服务必须用VisualSVN搭建,网上几乎没有这方面的文 ...

  6. AI - H2O - 第一个示例

    1 - Iris数据集 Iris数据集是常用的机器学习分类实验数据集,特点是数据量很小,可以快速学习. 数据集包含150个数据集,分为3类,每类50个数据,每个数据包含4个属性. Sepal.Leng ...

  7. 安装Vim插件——ViPlugin

    打开Eclipse,找到Help——Install New Software  Name输入 viPlugin ,Location输入 viplugin.com ,点击OK 之后同意协议,然后等待下载 ...

  8. eclipse英语单词1

    short cut bar 捷径,快捷方法 menu bar 菜单栏 tool bar 工具栏 workbench window 工作台窗口 perspective 透视 editor 编辑器 con ...

  9. matlab绘制直方图的方法

    直接上代码,利用hist绘制频次直方图和频率直方图... %rand Fs=1000;N=10000; t=0:1/Fs:(N-1)/Fs; X1=rand(1,length(t)); subplot ...

  10. 最新 迅游科技java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.迅游科技等10家互联网公司的校招Offer,因为某些自身原因最终选择了迅游科技.6.7月主要是做系统复习.项目复盘.Leet ...