定义和用途

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. 转 mysql mysql命令行中执行sql的几种方式总结

    https://www.jb51.net/article/96394.htm 1.直接输入sql执行 MySQL> select now(); +---------------------+ | ...

  2. Python中利用原始套接字进行网络编程的示例

    Python中利用原始套接字进行网络编程的示例 在实验中需要自己构造单独的HTTP数据报文,而使用SOCK_STREAM进行发送数据包,需要进行完整的TCP交互. 因此想使用原始套接字进行编程,直接构 ...

  3. antd 用 customize-cra 方式引入 sass

    antd 用 customize-cra 方式引入 sass 只需要安装:node-sass 即可

  4. 【k8s 硬盘监控】prometheus grafana

    设置监控哪块盘: https://www.bountysource.com/issues/50160777-disk-space-usage-depcited-in-grafana-correct h ...

  5. EC11编码器的使用方法

    1. EC11编码器的原理图如下 2. 旋转的时候,波形如下,EC11转1格,产生一个上升沿的中断,思路就是检测AX4-1的上升沿中断(平时是低电平),进入中断服务函数,检测AX4-2的电平,低电平逆 ...

  6. 【JS】实用/常用函数/Function方法

    1.获取日月 时分秒 //获取 月日 getMonth=(time)=>{ var date = new Date(time) <?):(date.getMonth()+) ?'+date ...

  7. use selenium+chromedriver to taobao automatically

    原理 利用chromedriver来驱动chrome进行各种模拟各种行为操作, 然后利用selenium提供的接口来操作chromedriver. 安装ChromeDriver 当然这个的默认前提是你 ...

  8. 019 Android 形状可绘制对象(根据要求绘制图片)+图片选择器

    1.目标效果 绘制颜色渐变的图片 2.实现方法 (1)在app--->res--->drawable 右击drawable文件夹右键,new ---->drawable resour ...

  9. HDOJ-1100 Trees made to order

    一.题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1100 二.题目分析 对二叉树的所有形态顺序编号,编号规则是:节点数越多的编号越大:节点数相等,左子 ...

  10. oracle 常用sql 经典sql函数使用 sql语法

    各种树操作, 用来查询表中带有子父节点的信息 Oracle 树操作(select-start with-connect by-prior) select m.org_id from sm_organ ...