定义和用途

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. oracle DBA 常用表和视图

    ☆dba_开头.....   dba_users      数据库用户信息   dba_segments  表段信息   dba_extents    数据区信息   dba_objects    数 ...

  2. 报错:Connection to node -1 could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)

    报错背景: 启动kafka消费者之后出现这种报错,持续打印相同信息. 报错现象: [root@master kafka_2.-]# /opt/kafka/kafka_2.-/bin/kafka-con ...

  3. SERVER_ADDR

    $_SERVER["SERVER_ADDR"]  当前运行脚本的服务器的ip地址

  4. JS正则验证数字格式2

    之前的博文:JS验证正数字,正则的一种正数规则1,中isNaN可以判断内容是否为数字,但是这种判断出来的数字,有的不是数字的标准格式.那篇博文中尝试了下用正则验证,但是忘了一种情况,小数点后无数字,小 ...

  5. 触屏Tap模拟事件

    触屏的click因为有双击判断所以有200ms的延迟,zepto里的touch.js兼容不好所以tap也没法直接用. gibhub上有个fastclick太大了. 自己用touched写个简单的模拟t ...

  6. virtualbox 安装扩展包 VirtualBox Extension Pack

    比如你下载的:Oracle_VM_VirtualBox_Extension_Pack-6.0.8.vbox-extpack ,双击安装没有反应. 可以在 VirtualBox 主菜单 管理-全局设定- ...

  7. Linux如何查看进程、杀死进程、启动进程

    1.查看进程:ps命令 下面的命令还没实践,仅仅供你参考:可以用man ps查看格式,只不过是一个小工具而已! ps a 显示现行终端机下的所有程序,包括其他用户的程序.    ps -A 显示所有程 ...

  8. [转帖]各种命令,以及FAQ..持续更新.....

    各种命令,以及FAQ..持续更新..... https://www.cnblogs.com/jicki/p/5548668.html Linux 篇: CentOs 7 修改主机名 hostnamec ...

  9. [转帖]crontab每小时运行一次

    crontab每小时运行一次     先给出crontab的语法格式 对于网上很多给出的每小时定时任务写法,可以说绝大多数都是错误的!比如对于下面的这种写法: 00 * * * * #每隔一小时执行一 ...

  10. Zuul【入门】

    1.创建eureka-server注册中心工程,配置跟之前讲eureka文章中一样,这里不再赘述 1.1.端口8888 2.创建一个demo-client工程 2.1.demo-client启动类跟之 ...