当前位置: 首页 > news >正文

Android的前台服务

概述

前台服务是用户主动意识到的一种服务,因此在内存不足时,系统也不会考虑将其终止。前台服务必须为状态栏提供通知,将其放在运行中的标题下方。这意味着除非将服务停止或从前台移除,否则不能清除该通知。

在 Android 8.0(API 级别 26)及更高版本中,系统对后台服务进行了限制,如果想要一直保持服务的运行就需要将服务设置为前台服务。前台服务与普通服务的区别在于它会有个通知在状态栏显示。当然有时可能也不仅仅是为了防止服务被回收才使用前台服务,有些项目的需要要求必须使用前台服务。如音乐播放、小说听书、天气等软件,这些都需要设置为前台服务,跟随进程的销毁而销毁。有些不仅仅是依赖应用进程,也可设置为系统白名单,保持一直运行的状态。

需要注意的是:应尽量限制应用使用前台服务。只有当应用执行的任务需供用户查看(即使该任务未直接与应用交互)时,您才应使用前台服务。因此,前台服务必须显示优先级为 PRIORITY_LOW 或更高的状态栏通知,这有助于确保用户知道应用正在执行的任务。如果某操作不是特别重要,您希望使用最低优先级通知,则可能不适合使用服务;此时,您可以考虑使用WorkManager、JobScheduler

每个运行服务的应用都会给系统带来额外负担,从而消耗系统资源。如果应用尝试使用低优先级通知隐藏其服务,则可能会降低用户正在主动交互的应用的性能。因此,如果某个应用尝试运行拥有最低优先级通知的服务,则系统会在抽屉式通知栏的底部调用出该应用的行为。

例如,应将服务播放音乐的音乐播放器设置为在前台运行,因为用户会明确意识到其操作。状态栏中的通知可能表示正在播放的歌曲,并且其允许用户通过启动 Activity 与音乐播放器进行交互。同样,如果应用允许用户追踪其运行,则需通过前台服务来追踪用户的位置。

注意:如果应用面向 Android 9(API 级别 28)或更高版本并使用前台服务,则其必须请求 FOREGROUND_SERVICE 权限。这是一种普通权限,因此,系统会自动为请求权限的应用授予此权限。如果面向 API 级别 28 或更高版本的应用试图创建前台服务但未请求 FOREGROUND_SERVICE,则系统会抛出 SecurityException。

有关前台服务的通知:如果您的应用正在运行“前台服务”(一种长时间在后台运行且用户可以察觉到的 Service,如媒体播放器),则需要发出通知。不能像关闭其他通知那样关闭这种通知。要移除此类通知,必须停止运行服务或者将其从“前台”状态中移除。如要从前台移除服务,请调用 stopForeground()。此方法接受布尔值参数,指示是否需同时移除状态栏通知。

应用场景

前台服务执行用户可以注意到的操作。前台服务显示一个状态栏通知,让用户知道你的应用程序正在前台执行任务,正在消耗系统资源。

应用程序使用前台服务的例子包括:

  • 一个在前台服务中播放音乐的音乐播放器应用程序。通知可能会显示当前正在播放的歌曲。
  • 一种健身应用程序,在获得用户的许可后,在前台服务中记录用户的跑步情况。该通知可能会显示用户在当前健身会话中走过的距离。

只有当你的应用需要执行用户可以注意到的任务时,才使用前台服务,即使他们没有直接与应用程序交互。如果操作的重要性足够低,你想使用最低优先级通知,那么创建一个后台任务。

本文介绍了使用前台服务所需的权限,以及如何启动前台服务并将其从后台移除。它还描述了如何将某些用例与前台服务类型相关联,以及当您从正在后台运行的应用程序启动前台服务时生效的访问限制。

前台服务的特点

默认情况下用户可取消前台服务

从Android 13 (API级别33)开始,默认情况下用户可以取消与前台服务相关的通知。此时只需要用户在通知上执行滑动手势即可。通常情况下,除非前台服务停止或从前台删除,否则通知不会被取消。

如果您希望通知不被用户划掉,则在使用notification.builder创建通知时将true传递给setOngoing() 方法。

立即显示通知的服务

如果前台服务有以下特征之一,系统在服务启动后立即显示相关的通知,即使在运行Android 12或更高版本的设备上:

  • 该服务与包含操作按钮的通知相关联。
  • 该服务的前台服务类型为mediaPlayback、mediaProjection或phoneCall。
  • 该服务提供了与电话呼叫、导航或媒体播放相关的用例,这些用例在通知的category属性中定义。
  • 在设置通知时,服务通过将FOREGROUND_SERVICE_IMMEDIATE传递给setForegroundServiceBehavior()来选择退出行为。
<manifest ...><uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" /><application ...><serviceandroid:name=".MyMediaPlaybackService"android:foregroundServiceType="mediaPlayback"android:exported="false"></service></application>
</manifest>

在Android 13 (API级别33)或更高版本上,如果用户拒绝通知权限,他们仍然会在任务管理器中看到与前台服务相关的通知,但在通知抽屉中看不到它们。

申请前台服务权限

针对Android 9 (API级别28)或更高版本并使用前台服务的应用程序需要请求FOREGROUND_SERVICE权限,如下面的代码片段所示。这是一个正常的权限,所以系统会自动将其授予请求应用程序。

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...><uses-permission android:name="android.permission.FOREGROUND_SERVICE"/><application ...>...</application>
</manifest>

注意:如果目标API级别为28或更高的应用程序试图创建前台服务而没有请求FOREGROUND_SERVICE权限,系统将抛出一个SecurityException。

启动一个前台服务

  • 紧接上文的案例,这里首先添加前台服务的权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
  • 在请求系统将某个服务作为前台服务运行之前,请先启动该服务本身: 在MainActivity中修改启动服务的方式如下:
//启动一个普通后台服务
//startService(startIntent);//启动一个前台服务 在api大于26才可使用startForegroundService此方法if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {startForegroundService(startIntent);}else{startService(startIntent);}
  • 在服务内部,通常是在onStartCommand() 中,你可以请求你的服务在前台运行。为此,调用startForeground()。此方法接受两个参数:一个在状态栏中唯一标识通知的正整数和notification对象本身。接着修改服务内部的代码:

首先创建一个通知,在MyService的oncreate方法和onStartCommand()方法中做如下修改:

public class MyService extends Service {public MyService() {}private Looper serviceLooper;private ServiceHandler serviceHandler;private NotificationManager manager;// 从当前线程接收消息的处理程序private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {try {Thread.sleep(5000);Log.i("Myservice","当前进程编号"+ Thread.currentThread().getName()+" ·····正在处理任务");} catch (InterruptedException e) {Thread.currentThread().interrupt();}//服务处理完成后,使用startId停止服务,这样我们就不会在停止处理另一个作业的服务
//            stopSelf(msg.arg1);}}@Overridepublic IBinder onBind(Intent intent) {// TODO: Return the communication channel to the service.throw new UnsupportedOperationException("Not yet implemented");}@Overridepublic void onCreate() {manager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);Log.i("Myservice","onCreate");//启动运行该服务的线程。因为默认情况下服务通常运行在进程的主线程中,我们不希望阻塞主线程。所以创建了一个单独的线程,// 我们还将其设置为后台优先级,这样cpu密集型工作就不会破坏我们的UI。HandlerThread thread = new HandlerThread("ServiceStartArguments",Process.THREAD_PRIORITY_BACKGROUND);thread.start();// Get the HandlerThread's Looper and use it for our HandlerserviceLooper = thread.getLooper();serviceHandler = new ServiceHandler(serviceLooper);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.i("Myservice","onStartCommand");// If the notification supports a direct reply action, use
// PendingIntent.FLAG_MUTABLE instead.Intent notificationIntent = new Intent(this, MainActivity.class);PendingIntent pendingIntent =PendingIntent.getActivity(this, 0, notificationIntent,PendingIntent.FLAG_IMMUTABLE);Notification notification =null;if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {//只在Android O之上需要渠道NotificationChannel notificationChannel = new NotificationChannel("channelid1","channelname",NotificationManager.IMPORTANCE_HIGH);//如果这里用IMPORTANCE_NOENE就需要在系统的设置里面开启渠道,通知才能正常弹出manager.createNotificationChannel(notificationChannel);notification = new Notification.Builder(this, "channelid1").setContentTitle(getText(R.string.notification_title)).setContentText(getText(R.string.notification_message)).setSmallIcon(R.drawable.ic_launcher_background).setContentIntent(pendingIntent).setTicker(getText(R.string.ticker_text)).build();}// Notification ID cannot be 0.startForeground(1, notification);Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();//对于每个开始请求,发送一个消息来开始一个作业,并传递启动ID,这样我们就知道当我们完成作业时我们正在停止哪个请求Message msg = serviceHandler.obtainMessage();msg.arg1 = startId;//在当前线程下执行服务的任务。serviceHandler.sendMessage(msg);// If we get killed, after returning from here, restartreturn START_STICKY;}@Overridepublic void onDestroy() {super.onDestroy();Log.i("Myservice","onDestroy");}
}

经过上述三步,我们来测试一下效果:

这会在前台开启一个通知,日志可见并没有进行销毁。服务列表中也可查看当前前台服务运行的时间:

这样一个前台任务就创建好了。

注意:状态栏通知必须使用优先级为PRIORITY_LOW或更高。如果你的应用程序试图使用一个优先级较低的通知,系统会在通知抽屉中添加一条消息,提醒用户应用程序使用了前台服务。

后台启动限制

针对Android 12 (API级别31)或更高版本的应用程序不能在后台运行时启动前台服务,除非有一些特殊情况。如果应用程序在后台运行时试图启动前台服务,而前台服务不满足前文中的情况,系统将抛出ForegroundServiceStartNotAllowedException异常。

注意:如果一个应用程序调用Context.startForegroundService()来启动另一个应用程序拥有的前台服务,这里限制只适用于两个应用程序都针对Android 12或更高版本。

检查应用程序是否执行后台启动

为了更好地验证当你的应用程序试图在后台运行时启动前台服务,可以在连接到测试设备或模拟器的开发机器上执行以下ADB命令,每当这种行为发生时就会出现通知:

adb shell device_config put activity_manager \ default_fgs_starts_restriction_notification_enabled true
免除后台启动限制

在以下情况下,即使你的应用程序在后台运行,应用程序也可以启动前台服务:

  • 你的应用从一个用户可见的状态转换,比如一个活动。
  • 当应用程序在一个现有任务的后台堆栈中有一个活动时,服务可以从后台启动一个活动。
  • 您的应用程序使用云消息接收高优先级消息。

注意:如果应用程序没有使用高优先级消息向用户显示时间敏感的内容,系统可以将高优先级消息降级为正常优先级。如果消息的优先级被降级,你的应用程序不能启动前台服务,并且试图启动前台服务会导致ForegroundServiceStartNotAllowedException异常。

因此,在尝试启动前台服务之前,建议检查RemoteMessage.getPriority() 的结果,并确认它是PRIORITY_HIGH。

  • 用户在与应用程序相关的UI元素上执行操作。例如,他们可能与气泡、通知、小部件或活动交互。
  • 应用程序调用精确的Alarm来完成用户请求的操作。
  • 应用程序是设备当前的输入法。
  • 应用程序接收到一个与地理围栏或活动识别转换相关的事件。
  • 在设备重启并在广播接收器中接收到ACTION_BOOT_COMPLETED、ACTION_LOCKED_BOOT_COMPLETED或action_my_package_replace意图动作后。
  • 应用程序在广播接收器中接收ACTION_TIMEZONE_CHANGED、ACTION_TIME_CHANGED或ACTION_LOCALE_CHANGED意图动作。
  • 具有特定系统角色或权限的应用程序,例如设备所有者和配置文件所有者。
  • ........

从前台删除一个服务

要从前台删除服务,请调用stopForeground()。此方法接受一个布尔值,该值指示是否也删除状态栏通知。如果在前台运行时停止服务,则会删除其通知。

    @Overridepublic void onDestroy() {super.onDestroy();if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {stopForeground(Service.STOP_FOREGROUND_REMOVE);}Log.i("Myservice","onDestroy");}

此时通知也会被移除。

相关文章:

Android的前台服务

概述 前台服务是用户主动意识到的一种服务&#xff0c;因此在内存不足时&#xff0c;系统也不会考虑将其终止。前台服务必须为状态栏提供通知&#xff0c;将其放在运行中的标题下方。这意味着除非将服务停止或从前台移除&#xff0c;否则不能清除该通知。 在 Android 8.0&…...

99%小白不知道,BI报表能自动生成

BI报表的制作步骤、操作方式都很简单&#xff0c;基本是有手就会&#xff0c;但在繁忙的工作中&#xff0c;还是有很多人没时间去从零开发BI报表。那怎么办呢&#xff1f;99%的小白或许都不知道&#xff0c;BI报表能自动生成。 是的&#xff0c;你没看错&#xff0c;就是由BI系…...

rabbitmq技术

1&#xff0c;docker运行rabbitmq docker run --restartalways -d --hostname my-rabbit --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq 2&#xff0c;新增管理员用户 rabbitmq服务&#xff0c;添加用户以及授权_rabbitmq添加用户授权_ROBOT玲玉的博客-CSDN博客...

鸿蒙4.0开发笔记之ArkTS语法基础之条件渲染和循环渲染的使用(十五)

文章目录 一、条件渲染&#xff08;if&#xff09;二、循环渲染&#xff08;ForEach&#xff09; 一、条件渲染&#xff08;if&#xff09; 1、定义 正如其他语言中的if…else…语句&#xff0c;ArkTS提供了渲染控制的能力&#xff0c;条件渲染可根据应用的不同状态&#xff0…...

电子设备电路分析(2)-----高速激光脉冲探测器

今天来介绍一个高速激光脉冲探测器&#xff0c;能够快速探测高速激光脉冲&#xff0c;该装置的独特性在于能够分辨上升时间在纳秒量级的脉冲。 光电二极管 高速激光脉冲探测器的核心是一个PIN二极管&#xff0c;也就是光电二极管。光电二极管是一种将光转换为电流的半导体器件…...

WordPress(9)宝塔配置Redis

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、宝塔安装Redis2、安装好先关闭Redis1、Redis密码默认是没有的二、安装php、Redis扩展1.启动Redis三.WordPress 安装Redis1.安装Redis插件2.启动Redis前言 提示:这里可以添加本文要记录的…...

【Qt之QSqlRelationalTableModel】描述及使用

描述 QSqlRelationalDelegate链接: https://blog.csdn.net/MrHHHHHH/article/details/134690139 QSqlRelationalTableModel类为单个数据库表提供了一个可编辑的数据模型&#xff0c;并支持外键。 QSqlRelationalTableModel的行为类似于QSqlTableModel&#xff0c;但允许将列设…...

【Openstack Train安装】四、MariaDB/RabbitMQ 安装

本章介绍了MariaDB/RabbitMQ的安装步骤&#xff0c;MariaDB/RabbitMQ仅需要在控制节点安装。 在安装MariaDB/RabbitMQ前&#xff0c;请确保您按照以下教程进行了相关配置&#xff1a; 【Openstack Train安装】一、虚拟机创建 【Openstack Train安装】二、NTP安装 【Opensta…...

工业级路由器在智能交通系统(ITS)中的创新应用

智能交通系统&#xff08;ITS&#xff09;作为一种先进的交通管理与控制系统&#xff0c;旨在提高交通运输系统的效率、安全性和便捷性。随着科技的不断发展&#xff0c;智能交通系统已经成为城市交通管理的重要组成部分。而工业级路由器作为一种可靠的网络通信设备&#xff0c…...

React立即更新DOM

正常情况下&#xff0c;react会等待set完毕后再进行页面渲染&#xff0c;所以在set时无法拿到更新后的dom import { useRef, useState } from "react"export default () > {const div useRef(null)const [count, setCount] useState(0)const btnClick () >…...

[JavaScript前端开发及实例教程]计算器井字棋游戏的实现

计算器&#xff08;网页内实现效果&#xff09; HTML部分 <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>My Calculator&l…...

数据结构 / 队列 / 循环队列 / 结构体定义和创建

1. 结构体定义 //head.h#ifndef __QUEUE_HEAD_H__ #define __QUEUE_HEAD_H__#include <string.h> #include <stdlib.h> #include <stdio.h>#define MAXSIZE 5 //循环队列最多元素个数typedef char datatype; //数据元素类型typedef struct {datatype data[M…...

Java零基础——Redis篇

1.【熟悉】NoSQL的简介 1.1 什么是NoSQL NoSQL 是 Not Only SQL 的缩写&#xff0c;意即"不仅仅是SQL"的意思&#xff0c;泛指非关系型的数据库。强调Key-Value Stores和文档数据库的优点。 NoSQL产品是传统关系型数据库的功能阉割版本&#xff0c;通过减少用不到或…...

分支和循环

通常来说&#xff0c;C语言是结构化的程序设计语言&#xff0c;这里的结构包括顺序结构、选择结构、循环结构&#xff0c;C语言能够实现这三种结构&#xff0c;如果我们仔细分析&#xff0c;我们日常生活中所见的事情都可以拆分为这三种结构或者它们的组合。 下面我会仔细讲解我…...

MyBatis-xml版本

MyBatis 是一款优秀的持久层框架 MyBatis中文网https://mybatis.net.cn/ 添加依赖 <dependencies><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47<…...

在eclipse中安装python插件:PyDev

在eclipse中安装插件PyDev&#xff0c;就可以在eclipse中开发python了。 PyDev的官网&#xff1a;https://www.pydev.org/ 不过可以直接在eclipse中用Marketplace安装&#xff08;备注&#xff1a;有可能一次安装不成功&#xff0c;是因为下载太慢了&#xff0c;多试几次&…...

25、pytest的测试报告插件allure

allure简介 在这里&#xff0c;你将找到使用allure创建、定制和理解测试报告所需的一切。开始让你的测试沟通更清晰&#xff0c;更有影响力。 Allure Report是一个实用程序&#xff0c;它处理由兼容的测试框架收集的测试结果并生成HTML报告。 安装allure 1、确保安装了Java…...

从零开始学习 JavaScript APl(七):实例解析关于京东案例头部案例和放大镜效果!

大家好关于JS APl 知识点已经全部总结了&#xff0c;第七部部分全部都是案例部分呢&#xff01;&#xff01;&#xff08;素材的可以去百度网盘去下载&#xff01;&#xff01;&#xff01;&#xff09; 目录 前言 一、个人实战文档 放大镜效果 思路分析&#xff1a; 关于其它…...

使用Pytoch实现Opencv warpAffine方法

随着深度学习的不断发展&#xff0c;GPU/NPU的算力也越来越强&#xff0c;对于一些传统CV计算也希望能够直接在GPU/NPU上进行&#xff0c;例如Opencv的warpAffine方法。Opencv的warpAffine的功能主要是做仿射变换&#xff0c;如果不了解仿射变换的请自行了解。由于Pytorch的图像…...

Hello World

世界上最著名的程序 from fastapi import FastAPIapp FastAPI()app.get("/") async def root():return {"message": "Hello World"}app.get("/hello/{name}") async def say_hello(name: str):return {"message": f"…...

【Python】Python读Excel文件生成xml文件

目录 ​前言 正文 1.Python基础学习 2.Python读取Excel表格 2.1安装xlrd模块 2.2使用介绍 2.2.1常用单元格中的数据类型 2.2.2 导入模块 2.2.3打开Excel文件读取数据 2.2.4常用函数 2.2.5代码测试 2.2.6 Python操作Excel官方网址 3.Python创建xml文件 3.1 xml语法…...

c++--类型行为控制

1.c的类 1.1.c的类关键点 c类型的关键点在于类存在继承。在此基础上&#xff0c;类存在构造&#xff0c;赋值&#xff0c;析构三类通用的关键行为。 类型提供了构造函数&#xff0c;赋值运算符&#xff0c;析构函数来让我们控制三类通用行为的具体表现。 为了清楚的说明类的构…...

笔记64:Bahdanau 注意力

本地笔记地址&#xff1a;D:\work_file\&#xff08;4&#xff09;DeepLearning_Learning\03_个人笔记\3.循环神经网络\第10章&#xff1a;动手学深度学习~注意力机制 a a a a a a a a a a a...

面试官问:如何手动触发垃圾回收?幸好昨天复习到了

在Java中&#xff0c;手动触发垃圾回收可以使用 System.gc() 方法。但需要注意&#xff0c;调用 System.gc() 并不能确保立即执行垃圾回收&#xff0c;因为具体的垃圾回收行为是由Java虚拟机决定的&#xff0c;而不受程序员直接控制。 public class GarbageCollectionExample …...

操作系统的运行机制+中断和异常

一、CPU状态 在CPU设计和生产的时候就划分了特权指令和非特叔指令&#xff0c;因此CPU执行一条指令前就能断出其类型 CPU有两种状态&#xff0c;“内核态”和“用户态” 处于内核态时&#xff0c;说明此时正在运行的是内核程序&#xff0c;此时可以执行特权指令。 处于用户态…...

Python实战:批量加密Excel文件指南

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 Python实战&#xff1a;批量加密Excel文件指南&#xff0c;全文3800字&#xff0c;阅读大约10分钟。 在日常工作中&#xff0c;保护敏感数据是至关重要的。本文将引导你通过…...

二叉树链式结构的实现和二叉树的遍历以及判断完全二叉树

二叉树的实现 定义结构体 我们首先定义一个结构来存放二叉树的节点 结构体里分别存放左子节点和右子节点以及节点存放的数据 typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right; }BTNode;…...

vue中的动画组件使用及如何在vue中使用animate.css

“< Transition >” 是一个内置组件&#xff0c;这意味着它在任意别的组件中都可以被使用&#xff0c;无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发&#xff1a; 由 v-if 所触发的切换由 v-show 所触…...

qt 5.15.2 网络文件下载功能

qt 5.15.2 网络文件下载功能 #include <QCoreApplication>#include <iostream> #include <QFile> #include <QTextStream> // #include <QtCore> #include <QtNetwork> #include <QNetworkAccessManager> #include <QNetworkRep…...

Wifi adb 操作步骤

1.连接usb 到主机 手机开起热点&#xff0c;电脑和车机连接手机&#xff0c;或者电脑开热点&#xff0c;车机连接电脑&#xff0c;车机和电脑连接同一个网络 因为需要先使用usb&#xff0c;后面切换到wifi usb 2.查看车机ip地址&#xff0c;和电脑ip地址 电脑win键r 输入cmd…...

汉中做网站/网络推广客服好做吗

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/feilengcui008/article/details/68942106 0. Abstract It achieves high utilization by combining admission control, efficient task-packing, over-commitment, and mach…...

那些是flash做的网站/西安霸屏推广

作为一名程序员&#xff0c;尤其是开发Android应用程序的程序员&#xff0c;不会自己折腾ROM简直就是一件不好意思的事情&#xff0c;于是乎我就费劲巴力的上网看资料&#xff0c;找工具&#xff0c;准备自己开始制作有“中国特色”的ROM&#xff0c;以下是解决的一些问题&…...

域名备案的网站名称/网站开发的基本流程

我没有能够得到任何这些解决方案的工作。我的目标是在一个笔记本上生成地块&#xff0c;并将它们发布到另一个笔记本中&#xff0c;因此坚持HTML的情节对于我来说并不重要&#xff0c;因为它只是有一些将剧情序列化到磁盘以在其他地方重建的方法。 我想出的解决方案是将fig对象…...

乐云seo商城网站建设/男生最喜欢的浏览器

声明&#xff1a; 以下内容为阅读由周志明编著的《深入理解Java虚拟机JVM高级特性与最佳实战》&#xff08;第二版&#xff09;自行总结记录&#xff0c;算不上完全解读了大神的意思&#xff0c;但也没有瞎写。如果写的不清楚的地方&#xff0c;还望能够自行阅读原著。这里写记…...

平顶山做网站的公司/市场推广计划方案模板

微信公众号搜索 DevOps和k8s全栈技术 &#xff0c;或者扫描文章最后的二维码&#xff0c;即可关注公众号&#xff0c;每天会分享技术文章供大家阅读参考哈~正文etcd 是基于 raft算法的分布式键值数据库&#xff0c;生来就为集群化而设计的&#xff0c;由于Raft算法在做决策时需…...

wordpress文章转移/做百度网站一年多少钱

方法&#xff1a;https://www.jianshu.com/p/7ee167911597...