您的位置:首页 > 移动开发 > Android开发

Android:(本地、可通信的、前台、远程)Service使用全面介绍

2016-11-14 16:22 393 查看


前言

Service作为Android四大组件之一,应用非常广泛

本文将介绍Service最基础的知识:Service的生命周期

如果你对Service还未了解,建议先阅读我写的文章:

Android四大组件:Service史上最全面解析

目录



1. Service分类

1.1 Service的类型



1.2 特点



2.具体使用解析

2.1 本地Service

这是最普通、最常用的后台服务Service。

2.1.1 使用步骤

步骤1:新建子类继承Service类

需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()方法

步骤2:构建用于启动Service的Intent对象

步骤3:调用startService()启动Service、调用stopService()停止服务

步骤4:在AndroidManifest.xml里注册Service

2.1.2 实例Demo

接下来我将用一个实例Demo进行本地Service说明

建议先下载Demo再进行阅读:(carson.ho的Github地址)Demo_for_Service

步骤1:新建子类继承Service类

需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()

MyService.java

public class MyService extends Service {

//启动Service之后,就可以在onCreate()或onStartCommand()方法里去执行一些具体的逻辑
//由于这里作Demo用,所以只打印一些语句
@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("执行了onStartCommand()");
return super.onStartCommand(intent, flags, startId);

}

@Override
public void onDestroy() {
super.onDestroy();
System.out.println("执行了onDestory()");
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}


步骤2:在主布局文件设置两个Button分别用于启动和停止Service

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="scut.carson_ho.demo_service.MainActivity">

<Button
android:layout_centerInParent="true"
android:id="@+id/startService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动服务" />

<Button
android:layout_centerInParent="true"
android:layout_below="@+id/startService"
android:id="@+id/stopService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止服务" />
</RelativeLayout>


步骤3:构建Intent对象,并调用startService()启动Service、stopService停止服务

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button startService;
private Button stopService;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

startService = (Button) findViewById(R.id.startService);
stopService = (Button) findViewById(R.id.stopService);

startService.setOnClickListener(this);
startService.setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {

//点击启动Service Button
case R.id.startService:
//构建启动服务的Intent对象
Intent startIntent = new Intent(this, MyService.class);
//调用startService()方法-传入Intent对象,以此启动服务
startService(startIntent);

//点击停止Service Button
case R.id.stopService:
//构建停止服务的Intent对象
Intent stopIntent = new Intent(this, MyService.class);
//调用stopService()方法-传入Intent对象,以此停止服务
stopService(stopIntent);

}
}
}


步骤4:在AndroidManifest.xml里注册Service

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="scut.carson_ho.demo_service">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

</activity>

//注册Service服务
<service android:name=".MyService">
</service>

</application>

</manifest>


Androidmanifest里Service的常见属性说明

属性说明备注
android:nameService的类名
android:labelService的名字若不设置,默认为Service类名
android:iconService的图标
android:permission申明此Service的权限有提供了该权限的应用才能控制或连接此服务
android:process表示该服务是否在另一个进程中运行(远程服务)不设置默认为本地服务;remote则设置成远程服务
android:enabled系统默认启动true:Service 将会默认被系统启动;不设置则默认为false
android:exported该服务是否能够被其他应用程序所控制或连接不设置默认此项为 false

2.1.3 测试结果



2.1.4 Demo地址

Carson.ho的Github地址:Demo_for_Service

2.2 可通信的服务Service

上面介绍的Service是最基础的,但只能单机使用,即无法与Activity通信

接下来将在上面的基础用法上,增设“与Activity通信”的功能,即使用绑定Service服务(Binder类、bindService()、onBind()、unbindService()、onUnbind())

2.2.1 实例Demo

接下来我将用一个实例Demo进行可通信的服务Service说明

建议先下载Demo再进行阅读:(carson.ho的Github地址)Demo_for_Service

步骤1:在新建子类继承Service类,并新建一个子类继承自Binder类、写入与Activity关联需要的方法、创建实例

public class MyService extends Service {

private MyBinder mBinder = new MyBinder();

@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("执行了onStartCommand()");
return super.onStartCommand(intent, flags, startId);

}

@Override
public void onDestroy() {
super.onDestroy();
System.out.println("执行了onDestory()");
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
System.out.println("执行了onBind()");
//返回实例
return mBinder;
}

@Override
public boolean onUnbind(Intent intent) {
System.out.println("执行了onUnbind()");
return super.onUnbind(intent);
}

//新建一个子类继承自Binder类
class MyBinder extends Binder {

public void service_connect_Activity() {
System.out.println("Service关联了Activity,并在Activity执行了Service的方法");

}
}
}


步骤2:在主布局文件再设置两个Button分别用于绑定和解绑Service

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="scut.carson_ho.demo_service.MainActivity">

<Button
android:layout_centerInParent="true"
android:id="@+id/startService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动服务" />

<Button
android:layout_centerInParent="true"
android:layout_below="@+id/startService"
android:id="@+id/stopService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止服务" />

<Button
android:layout_centerInParent="true"
android:layout_below="@id/stopService"
android:id="@+id/bindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绑定服务" />

<Button
android:layout_centerInParent="true"
android:layout_below="@id/bindService"
android:id="@+id/unbindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="解绑服务"
/>
</RelativeLayout>


步骤3:在Activity通过调用MyBinder类中的public方法来实现Activity与Service的联系

即实现了Activity指挥Service干什么Service就去干什么的功能

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button startService;
private Button stopService;
private Button bindService;
private Button unbindService;

private MyService.MyBinder myBinder;

//创建ServiceConnection的匿名类
private ServiceConnection connection = new ServiceConnection() {

//重写onServiceConnected()方法和onServiceDisconnected()方法
//在Activity与Service建立关联和解除关联的时候调用
@Override
public void onServiceDisconnected(ComponentName name) {
}

//在Activity与Service解除关联的时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//实例化Service的内部类myBinder
//通过向下转型得到了MyBinder的实例
myBinder = (MyService.MyBinder) service;
//在Activity调用Service类的方法
myBinder.service_connect_Activity();
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

startService = (Button) findViewById(R.id.startService);
stopService = (Button) findViewById(R.id.stopService);

startService.setOnClickListener(this);
stopService.setOnClickListener(this);

bindService = (Button) findViewById(R.id.bindService);
unbindService = (Button) findViewById(R.id.unbindService);

bindService.setOnClickListener(this);
unbindService.setOnClickListener(this);

}

@Override
public void onClick(View v) {
switch (v.getId()) {

//点击启动Service
case R.id.startService:
//构建启动服务的Intent对象
Intent startIntent = new Intent(this, MyService.class);
//调用startService()方法-传入Intent对象,以此启动服务
startService(startIntent);
break;

//点击停止Service
case R.id.stopService:
//构建停止服务的Intent对象
Intent stopIntent = new Intent(this, MyService.class);
//调用stopService()方法-传入Intent对象,以此停止服务
stopService(stopIntent);
break;

//点击绑定Service
case R.id.bindService:
//构建绑定服务的Intent对象
Intent bindIntent = new Intent(this, MyService.class);
//调用bindService()方法,以此停止服务

bindService(bindIntent,connection,BIND_AUTO_CREATE);
//参数说明
//第一个参数:Intent对象
//第二个参数:上面创建的Serviceconnection实例
//第三个参数:标志位
//这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service
//这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行
break;

//点击解绑Service
case R.id.unbindService:
//调用unbindService()解绑服务
//参数是上面创建的Serviceconnection实例
unbindService(connection);
break;

default:
break;

}
}
}


2.2.2 测试结果



2.2.3 Demo

carson.ho的Github地址:Demo_for_Service

2.3 前台Service

前台Service和后台Service(普通)最大的区别就在于:

前台Service在下拉通知栏有显示通知(如下图),但后台Service没有;



前台Service优先级较高,不会由于系统内存不足而被回收;后台Service优先级较低,当系统出现内存不足情况时,很有可能会被回收

2.3.1 具体使用

用法很简单,只需要在原有的Service类对onCreate()方法进行稍微修改即可,如下图:

@Override
public void onCreate() {
super.onCreate();
System.out.println("执行了onCreat()");

//添加下列代码将后台Service变成前台Service
//构建"点击通知后打开MainActivity"的Intent对象
Intent notificationIntent = new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);

//新建Builer对象
Notification.Builder builer = new Notification.Builder(this);
builer.setContentTitle("前台服务通知的标题");//设置通知的标题
builer.setContentText("前台服务通知的内容");//设置通知的内容
builer.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标
builer.setContentIntent(pendingIntent);//设置点击通知后的操作

Notification notification = builer.getNotification();//将Builder对象转变成普通的notification
startForeground(1, notification);//让Service变成前台Service,并在系统的状态栏显示出来

}


2.3.2 测试结果

运行后,当点击Start Service或Bind Service按钮,Service就会以前台Service的模式启动(通知栏上有通知),如下图



2.4 远程Service

具体请看我写的另外一篇文章:

Android:远程服务Service(含AIDL & IPC讲解)

3. 使用场景

通过上述描述,你应该对Service类型及其使用非常了解;

那么,我们该什么时候用哪种类型的Service呢?

各种Service的使用场景请看下图:



4. 总结

本文对Service的使用进行了全面解析(本地、可通信、前台和远程Service)

如果你还想了解关于Service的其他知识,请浏览以下文章:

Android四大组件:Service史上最全面解析

Android:Service生命周期最全面解析

Android:(本地、可通信的、前台、远程)Service使用全面介绍

Android:远程服务Service(含AIDL & IPC讲解)

Android多线程全面解析:IntentService用法&源码

接下来会介绍继续介绍Android开发中的相关知识,有兴趣可以继续关注Carson_Ho的安卓开发笔记

请点赞!因为你们的赞同/鼓励是我写作的最大动力!

欢迎关注Carson_Ho的简书!

不定期分享关于安卓开发的干货,追求短、平、快,但却不缺深度

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: