资讯专栏INFORMATION COLUMN

Service 使用详解

freewolf / 2344人阅读

摘要:只能执行单一操作,无法返回结果给调用方,常用于网络下载上传文件,播放音乐等。绑定模式此模式通过绑定组件等调用启动此服务随绑定组件的消亡而解除绑定。

极力推荐文章:欢迎收藏
Android 干货分享

阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android

本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:

Service 简介

四大组件之一,必须在Androidmainfest.xml 中注册

启动模式启动服务

绑定模式绑定服务

前台服务

AIDL远程服务

Service Android 四大组件之一(Activity 活动,Service 服务,ContentProvider 内容提供者,BroadcastReceiver 广播),与Activity相比,Activity 是运行在前台,用户可以看得见,Service 则是运行在后台,无用户界面,用户无法看到。

Service主要用于组件之间交互(例如:与ActivityContentProviderBroadcastReceiver进行交互)、后台执行耗时操作等(例如下载文件,播放音乐等,但Service在主线程运行时长不能超过20s,否则会出现ANR,耗时操作一般建议在子线程中进行操作)。

1.Service 简介

在了解Service 的生命周期的之前,我们先了解一下Service 的继承关系,方便我们更好的了解Service

Service 继承关系如下:
java.lang.Object
   ↳    android.content.Context
        ↳    android.content.ContextWrapper
             ↳    android.app.Service
Service 的两种启动模式

Service 有两种不同的启动模式 ,不同的启动模式对应不同生命周期.
Service 启动模式主要分两种: 1. 启动模式。 2. 绑定模式。

1.启动模式

此模式通过 startService()方法启动,此服务可以在后台一直运行,不会随启动组件的消亡而消亡。只能执行单一操作,无法返回结果给调用方,常用于网络下载、上传文件,播放音乐等。

2.绑定模式

此模式 通过绑定组件(Activity等)调用 bindService() 启动,此服务随绑定组件的消亡而解除绑定。

如果此时没有其它通过startService()启动,则此服务会随绑定组件的消亡而消亡。
多个组件不仅可以同时绑定一个Service,而且可以通过进程间通信(IPC)执行跨进程操作等。

3.两种服务可以同时运行

启动模式与绑定模式的服务可以同时运行,在销毁服务时,只有两种模式都不在使用Service时候,才可以销毁服务,否则会引起异常。

4. 两种 Service 模式的生命周期

两种 Service 模式的生命周期如下:

2.四大组件之一,必须在Androidmainfest.xml 中注册 Service 注册方法如下:

  ...
  
      
      ...
  
注意:

Service 如不注册 ,不会像Activity 那样会导致App CrashService 不注册 不会报异常信息,但是服务会起不来,如不注意很容易迷惑。

3.启动模式

通过启动模式启动的Service ,如不主动关闭,Service会一直在。

启动模式启动服务的方法
        Intent  mBindIntent = new Intent(ServiceMethods.this, BindServiceMethods.class);
        startService(mStartIntent);
启动模式启动服务的生命周期

下面是验证启动模式启动服务的生命周期的方法,详细生命周期请查看上方Service的生命周期图。

01-03 17:16:36.147 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onCreate----
01-03 17:16:36.223 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onStartCommand----
01-03 17:16:38.174 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onDestroy----
启动模式 启动服务案例

此案例功能:启动服务,在服务中创建通知

    // Service 创建方法
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "----onCreate----");
    }
    // Service  启动方法
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "----onStartCommand----");
        // 获取NotificationManager实例
        notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        // 实例化NotificationCompat.Builder并设置相关属性
        NotificationCompat.Builder builder = new NotificationCompat.Builder(
                this)
        // 设置小图标
                .setSmallIcon(R.drawable.ic_launcher)
                .setLargeIcon(
                        BitmapFactory.decodeResource(getResources(),
                                R.drawable.ic_launcher))
                // 设置通知标题
                .setContentTitle("我是通过StartService服务启动的通知")
                // 设置通知不能自动取消
                .setAutoCancel(false).setOngoing(true)
                // 设置通知时间,默认为系统发出通知的时间,通常不用设置
                // .setWhen(System.currentTimeMillis())
                // 设置通知内容
                .setContentText("请使用StopService 方法停止服务");

        // 通过builder.build()方法生成Notification对象,并发送通知,id=1
        notifyManager.notify(1, builder.build());

        return super.onStartCommand(intent, flags, startId);
    }
    // Service  销毁方法
    @Override
    public void onDestroy() {
        Log.i(TAG, "----onDestroy----");
        notifyManager.cancelAll();
        super.onDestroy();
    }
4. 绑定模式启动绑定服务

绑定模式启动的服务会随着绑定逐渐的消亡而解除Service绑定,如果此时Service没有通过启动模式启动,则此服务将会被销毁。

绑定模式启动绑定服务的方法

绑定模式,是通过其他组件启动的Service

启动绑定模式服务的方法
    // 启动绑定服务处理方法
    public void BtnStartBindService(View view) {
        // 启动绑定服务处理方法
        bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
        isBindService = true;
        Toast.makeText(ServiceMethod.this, "启动 " + mBindCount + " 次绑定服务",
                Toast.LENGTH_SHORT).show();
    }

    
    public void BtnSopBindService(View view) {
        if (isBindService) {
            // 解除绑定服务处理方法
            unbindService(serviceConnection);
            Toast.makeText(ServiceMethod.this, "解除 " + mUnBindCount + " 次绑定服务",
                    Toast.LENGTH_SHORT).show();
            isBindService = false;
        }

    }

绑定服务 随绑定组件的消亡而消亡

绑定模式 生命周期回调代码如下:
    // Service 创建方法
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "----onCreate----");
    }

    // Service 绑定方法
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "----onBind----");

        MyBinder myBinder = new MyBinder();
        return myBinder;
    }

    // Service 解除绑定方法
    @Override
    public boolean onUnbind(Intent intent) {

        Log.i(TAG, "----onUnbind----");
        return super.onUnbind(intent);

    }

    // Service 销毁方法
    @Override
    public void onDestroy() {
        Log.i(TAG, "----onDestroy----");
        super.onDestroy();
    }

绑定服务的生命周期代码打印Log信息如下:

01-03 20:32:59.422 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onCreate----
01-03 20:32:59.423 13306-13306/com.android.program.programandroid I/BindService wjwj:: -----onBind-----
01-03 20:33:09.265 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onUnbind----
01-03 20:33:09.266 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onDestroy----
绑定服务案例

功能:获取绑定模式启动 绑定服务及解除绑定服务的次数

绑定服务类
package com.android.program.programandroid.component.Service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class BindServiceMethods extends Service {
    private static final String TAG = "BindService wjwj:";

    public BindServiceMethods() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "----onCreate----");
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "----onBind----");

        MyBinder myBinder = new MyBinder();
        return myBinder;
    }


    @Override
    public boolean onUnbind(Intent intent) {

        Log.i(TAG, "----onUnbind----");
        return super.onUnbind(intent);

    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "----onDestroy----");
        super.onDestroy();
    }
}

组件与绑定服务类之间的交互

 //    启动绑定服务处理方法
    public void BtnStartBindService(View view) {

        bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
        isBindService = true;
        Toast.makeText(ServiceMethods.this,"启动 "+mBindCount+" 次绑定服务",Toast.LENGTH_SHORT).show();
    }

    //    解除绑定服务处理方法
    public void BtnSopBindService(View view) {
        if (isBindService) {
            unbindService(serviceConnection);
            Toast.makeText(ServiceMethods.this,"解除 "+mUnBindCount+" 次绑定服务",Toast.LENGTH_SHORT).show();
            isBindService=false;
        }

    }

组件之间交互所需的 Binder 接口类

/**
* 该类提供 绑定组件与绑定服务提供接口
* */
public class MyBinder extends Binder {
   private int count = 0;

    public int getBindCount() {
        return ++count;
    }
    public int getUnBindCount() {
        return count> 0 ? count-- : 0;
    }
}
5. 提高服务的优先级

服务默认启动方式是后台服务,但是可以通过设置服务为前台服务,提高服务的优先级,进而避免手机内存紧张时,服务进程被杀掉。

设置前台服务的两种方法

1.设置为前台服务

//设置为前台服务
startForeground(int, Notification)

2.取消前台服务

//取消为前台服务
stopForeground(true);
startForeground 前台服务案例

功能:前台服务绑定通知信息,提高服务进程优先级,否则取消通知信息

package com.android.program.programandroid.component.Service;

import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;

import com.android.program.programandroid.R;

public class MyStartForcegroundService extends Service {

    public MyStartForcegroundService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent.getAction().equals("start_forceground_service")) {

//        获取NotificationManager实例
            NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//        实例化NotificationCompat.Builder并设置相关属性
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
//                设置小图标
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
//                设置通知标题
                    .setContentTitle("我是通过startForeground 启动前台服务通知")
//                设置通知不能自动取消
                    .setAutoCancel(false)
                    .setOngoing(true)
//                设置通知时间,默认为系统发出通知的时间,通常不用设置
//                .setWhen(System.currentTimeMillis())
//               设置通知内容
                    .setContentText("请使用stopForeground 方法改为后台服务");

            //通过builder.build()方法生成Notification对象,并发送通知,id=1
//        设置为前台服务
            startForeground(1, builder.build());

        } else if (intent.getAction().equals("stop_forceground_service")) {
            
            stopForeground(true);
        }

        return super.onStartCommand(intent, flags, startId);
    }
}
6. 使用AIDL接口实现远程绑定

由于内容较多,后续另开一篇详细介绍。

至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75818.html

相关文章

  • service-worker用法详解

    摘要:二简要介绍是一段脚本,在后台运行。作为一个独立的线程,不会对页面造成阻塞。本质上充当应用程序与浏览器之间的代理服务器。可以做到离线使用消息推送后台自动更新,的出现是正是为了使得也可以具有类似的能力。在我们的例子例,是在,的根目录是。 一、背景 taro框架转的h5,想在无网络状态下可以控制展示给用户的界面,使用客户端离线缓存可以达到目的,并且可以将静态资源进行缓存,从而减少白屏时间,加...

    104828720 评论0 收藏0
  • SpringAOP面向切面详解(带实例)

    摘要:了解的相关术语通知通知定义了切面是什么,以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。就是用来配置切面设置代理模式。 了解AOP的相关术语 1.通知(Advice): 通知定义了切面是什么,以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。 2.连接点(Joinpoint): 程序能够应用通知的一个时机,这些时机就是连接点,例如方法被调用时、异常被抛出时等等。 ...

    马忠志 评论0 收藏0
  • CentOS 开机启动服务详解

    摘要:样例启动服务启动服务文件说明参数说明服务的说明描述服务描述服务类别服务运行参数的设置是后台运行的形式为服务的具体运行命令为重启命令为停止命令表示给服务分配独立的临时空间服务安装的相关设置,可设置为多用户注意启动重启停止命样例:启动 Seahub 服务[Unit] Description=Seafile Seahub After=network.target seafile.service...

    Tecode 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<