0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

了解一下Service的继承关系

哆啦安全 来源:哆啦安全 2023-04-28 15:48 次阅读

一、Service 简介

首先我们先了解一下Service的继承关系,方便我们更好的了解ServiceService继承关系如下:

java.lang.Object
   ↳    android.content.Context
       ↳    android.content.ContextWrapper
           ↳    android.app.Service

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

Service主要用于组件之间交互(例如:与ActivityContentProviderBroadcastReceiver进行交互)、执行后台任务等(例如下载文件,播放音乐等)。

注意:Service在主线程运行时长不能超过20s,否则会出现ANR,耗时操作一般建议在子线程或工作线程中进行操作。

二、Service 的注册

Service是四大组件之一,必现在AndroidMainfest.xml中注册。
Service注册方法如下:

 ... >
  ...
   ... >
       android:name=".ServiceMethods" />
      ...
  >
>

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

三、Service 的启动模式

Service启动模式主要分两种:1. 启动模式。2. 绑定模式。

  • 1.启动模式

此模式通过startService()方法启动,此服务可以在后台一直运行,不会随启动组件的消亡而消亡。

但是,此种启动模式只能执行单一操作,并且无法返回结果给调用方,主要常用于网络下载、上传文件,播放音乐等。

  • 2.绑定模式

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

如果此时没有其它通过startService()启动,则此服务会随绑定组件的消亡而消亡。

多个组件不仅可以同时绑定一个Service,而且可以通过进程间通信(IPC)执行跨进程操作等。

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

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

四、Service的生命周期

Service有两种不同的启动模式 ,不同的启动模式对应不同生命周期。两种不同Service模式的生命周期如下:

e9bfc102-e572-11ed-ab56-dac502259ad0.jpg

两种 Service 模式生命周期图

五、启动模式使用举例

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

1.启动模式启动服务的方法

        Intent  mBindIntent = new Intent(ServiceMethods.this, BindServiceMethods.class);
        startService(mStartIntent);

2.启动模式启动服务的生命周期

下面是验证启动模式启动服务的生命周期的方法,详细生命周期请查看上方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----

3.启动模式 启动服务案例

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

    // 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();
    }

六、 绑定服务介绍

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

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

绑定模式,是通过其他组件调用bindService()方法启动的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;
        }

    }

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

如果绑定服务的组件被destory,这 bind 服务会走到onUnbind()方法。

3. 绑定模式 生命周期回调代码如下:

    // 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----

七、bind 服务举例

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

1.绑定服务类

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();
    }
}

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

 //    启动绑定服务处理方法
    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;
        }

    }

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

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

    public int getBindCount() {
        return ++count;
    }
    public int getUnBindCount() {
        return count> 0 ? count-- : 0;
    }
}

八、服务的优先级

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

设置服务优先级的方法如下:

1.设置为前台服务

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

2.取消前台服务

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

3.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);
    }
}


审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Service
    +关注

    关注

    0

    文章

    30

    浏览量

    13784
  • 组件
    +关注

    关注

    1

    文章

    512

    浏览量

    17813
  • 线程
    +关注

    关注

    0

    文章

    504

    浏览量

    19675

原文标题:八、服务的优先级

文章出处:【微信号:哆啦安全,微信公众号:哆啦安全】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    求大神详细介绍一下关于类的封装与继承

    求大神详细介绍一下关于类的封装与继承
    发表于 04-28 06:40

    了解一下STM32的时钟树

    的时钟频率又是如何确定的呢?带着这个问题,我们起详细了解一下STM32的时钟树。时钟树是了解STM32时钟的灵魂,ST...
    发表于 08-06 07:11

    USB显微镜,不想了解一下吗?

    USB显微镜,不想了解一下吗? 近日,在很多国外网站上都搜的到配备了USB接口的数字显微镜,他们打破了传统显微镜机体笨重,操作复杂的传统,
    发表于 04-28 10:24 3531次阅读

    Java类的继承与派生

    一下与类的初始化相关的东西,然后再从几个方面阐述继承大特性。以下是本文的目录大纲: 。你了解类吗? 二。你
    发表于 09-27 10:55 0次下载
    Java类的<b class='flag-5'>继承</b>与派生

    了解OOP三大特点中继承的优缺点

    程序员来说,OOP(面向对象编程)的三大特性——数据封装、继承和多态通常是面试中的重点考察问题,因此大部分人对此也相当熟悉。 不过,OOP的优缺点你真的了解吗?今天这篇文章会带领大家了解
    的头像 发表于 02-06 14:54 8628次阅读
    <b class='flag-5'>了解</b>OOP三大特点中<b class='flag-5'>继承</b>的优缺点

    宏碁智能佛珠了解一下

    朋友,最近工作顺利吗?家庭幸福吗?生活美满吗?看你心情复杂,要不要了解一下宏碁刚发布的智能佛珠?
    的头像 发表于 08-08 16:27 3551次阅读

    带你了解一下什么是USB 3.1接口

    尽管USB是外部设备中最常见的连接,但它有很多的版本,不同的接头和连接类型都令人困惑不解。USB 3.1是当今最常见的标准之,但它究竟是什么呢?它与之前和之后的版本有什么不同?让我们来详细了解一下
    发表于 09-23 17:31 1.7w次阅读

    电磁炉加热一下就停一下什么原因

    电磁炉加热一下就停一下什么原因。
    的头像 发表于 06-04 10:01 3.8w次阅读

    python类的继承详解

    python类的继承 类的继承,跟人类繁衍的关系相似。 被继承的类称为基类(也叫做父类),继承而得的类叫派生类(也叫子类),这种
    的头像 发表于 03-08 16:40 3095次阅读

    了解一下AOC有源光缆的相关知识

    信息传输与交换量与日俱增,高密度,高宽带应用也越来越多,传统的铜质电缆已经不能适应通信的需要,相比于传统线缆来说,有源光缆能够帮助通信设备享受到光传输的巨大优势。那AOC有源光缆有什么不同呢?今天就跟易天光通信(ETU-LINK)一起来了解一下AOC有源光缆的相关知识吧!
    的头像 发表于 03-25 08:58 2269次阅读

    大哥!100W移动电源方案,了解一下

    100W移动电源方案,了解一下
    的头像 发表于 06-02 19:03 2430次阅读
    大哥!100W移动电源方案,<b class='flag-5'>了解</b><b class='flag-5'>一下</b>

    了解一下光纤传输的特点

    光纤作为综合布线种常见的传输媒介,很多人搞不清楚光纤和光缆这两者,光纤是光传导工具,传输原理是“光的全反射”,被用作长距离的信息传递,下面跟着科兰小编一起来了解一下光纤传输的特点。
    的头像 发表于 06-08 13:42 843次阅读

    虹科带你来了解一下汽车以太网和TSN的测试标准

    虹科带你来了解一下汽车以太网和TSN的测试标准
    的头像 发表于 12-22 17:46 3527次阅读
    虹科带你来<b class='flag-5'>了解</b><b class='flag-5'>一下</b>汽车以太网和TSN的测试标准

    了解一下“薄膜厚度监控”

    光学镀膜干货来了!了解一下“薄膜厚度监控”
    的头像 发表于 07-20 10:11 859次阅读
    <b class='flag-5'>了解</b><b class='flag-5'>一下</b>“薄膜厚度监控”

    无需电流采样电阻的智能电机驱动IC,不来了解一下么?

    无需电流采样电阻的智能电机驱动IC,不来了解一下么?
    的头像 发表于 11-30 17:43 451次阅读
    无需电流采样电阻的智能电机驱动IC,不来<b class='flag-5'>了解</b><b class='flag-5'>一下</b>么?