定义和用途

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. Python - Django - ORM 一对一表结构

    当一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁,可以把不怎么常用的字段 单独拿出来做成一张表,然后用一对一的表关联起来 这样既保证数据都完整的保存下来,又能保证检索更快 model ...

  2. Python - Django - 命名空间模式

    新建一个项目 app02 在 app02/ 下创建 urls.py: from django.conf.urls import url from app02 import views urlpatte ...

  3. [ kvm ] 学习笔记 1:Linux 操作系统及虚拟化

    1. 前言 一台计算机是由一堆硬件设备组合而成,在硬件之上是操作系统,操作系统与计算机硬件密不可分,操作系统用来管理所有的硬件资源提供服务,各个硬件设备是通过 总线 进行连接起来的: 在操作系统之上, ...

  4. ubuntu18.04安装flat-remix-gnome主题

    flat-remix-gnome主题的github地址:https://github.com/daniruiz/flat-remix-gnome ubuntu下进行如下操作: sudo add-apt ...

  5. Java以UTF-8格式读写及追加写文件示例

    package test; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; im ...

  6. PHP5.2\5.3 Xdebug 调试器配置及应用

    PHP5.2添加的扩展方式:zend_extension_ts=D:\www\Server\php5\ext\php_xdebug-2.1.0-5.2-vc6.dll PHP5.3添加的扩展方式:ze ...

  7. 图解 perspective && perspective-origin && transform3d && transform-origin

    perspective && perspective-origin perspective是物体相对于画布的视距距离 perspective-origin是物体在画布位置的中心视点 t ...

  8. centos7之zabbix监控DELL磁盘阵列

    本篇我们介绍戴尔服务器R730.R720.R710等服务器下挂在的MD1200磁盘阵列柜监控方式 一.使用场景 在生产环境中存储肯定是离不开的,服务器自带的硬盘卡槽有限,所以一般需要存储的量大的话,都 ...

  9. RabbitMQ官方教程三 Publish/Subscribe(GOLANG语言实现)

    RabbitMQ官方教程三 Publish/Subscribe(GOLANG语言实现) 在上一个教程中,我们创建了一个工作队列. 工作队列背后的假设是,每个任务都恰好交付给一个worker处理. 在这 ...

  10. 【GStreamer开发】GStreamer播放教程03——pipeline的快捷访问

    目的 <GStreamer08--pipeline的快捷访问>展示了一个应用如何用appsrc和appsink这两个特殊的element在pipeline中手动输入/提取数据.playbi ...