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

Android Jetpack 中Hilt的使用

Hilt 是 Android 的依赖项注入库,可减少在项目中执行手动依赖项注入的样板代码。执行 手动依赖项注入 要求您手动构造每个类及其依赖项,并借助容器重复使用和管理依赖项。

Hilt 通过为项目中的每个 Android 类提供容器并自动管理其生命周期,提供了一种在应用中使用 DI(依赖项注入)的标准方法。Hilt 在热门 DI 库 Dagger 的基础上构建而成,因而能够受益于 Dagger 的编译时正确性、运行时性能、可伸缩性和 Android Studio 支持。本篇只探讨其使用方式,其步骤如下

在项目中引入Hilt。

project/build.gradle下加入kotlin和hilt的插件

buildscript {ext.kotlin_version = '1.5.31'ext.hilt_version = '2.40'repositories {google()mavenCentral()}dependencies {classpath 'com.android.tools.build:gradle:7.0.3'//kotlin编译插件classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//hilt编译插件classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"}
}

app/build.gradle下加入kotlin和hilt

plugins {id 'com.android.application'id 'kotlin-android'id 'kotlin-parcelize'id 'kotlin-kapt'id 'dagger.hilt.android.plugin'
}android {compileSdkVersion 31buildToolsVersion "30.0.3"defaultConfig {applicationId "com.example.android.hilt"minSdkVersion 16targetSdkVersion 31versionCode 1versionName "1.0"javaCompileOptions {annotationProcessorOptions {arguments["room.incremental"] = "true"}}}compileOptions {sourceCompatibility 1.8targetCompatibility 1.8}
}dependencies {implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"implementation 'androidx.appcompat:appcompat:1.3.1'implementation 'androidx.core:core-ktx:1.7.0'implementation 'androidx.constraintlayout:constraintlayout:2.1.1'implementation 'androidx.recyclerview:recyclerview:1.2.1'// Roomimplementation "androidx.room:room-runtime:2.3.0"kapt "androidx.room:room-compiler:2.3.0"// Hilt dependenciesimplementation "com.google.dagger:hilt-android:$hilt_version"kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
}

在项目中使用hilt。

Step1:使用@HiltAndroidApp注解

新建继承自Application的类并添加注解@HiltAndroidApp,触发 Hilt 的代码生成,其中包括可以使用依赖项注入的应用基类。应用容器是应用的父容器,这意味着其他容器可以访问其提供的依赖项。

@HiltAndroidApp 
class LogApplication : Application()

Step2:使用@AndroidEntryPoint将依赖注入Android类。

在 Application 类中设置了 Hilt 且有了应用级组件后,Hilt 可以为带有 @AndroidEntryPoint 注解的其他 Android 类提供依赖项。Hilt 目前支持以下 Android 类:

  • Application(通过使用 @HiltAndroidApp)
  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver

如果您使用 @AndroidEntryPoint 为某个 Android 类添加注解,则还必须为依赖于该类的 Android 类添加注解。例如,如果您为某个 Fragment 添加注解,则还必须为使用该 Fragment 的所有 Activity 添加注解。

@AndroidEntryPoint 
class LogsFragment : Fragment() { .... }

Step3:使用hilt进行字段注入

@Inject 注解让 Hilt 注入不同类型的实例。其实就是声明变量的时候用上这个注解

@AndroidEntryPoint
class LogsFragment : Fragment() {@Inject lateinit var logger: LoggerLocalDataSource@Inject lateinit var dateFormatter: DateFormatter...
}

Step4:Hilt提供实例。

step4-condition1:在构造器上利用@Inject获取实例。

对于用@Inject注解的变量,提供其实例时,如果是通过构造器创建的实例那么我们可以直接在构造器上利用@Inject注解就可以让hilt为我们创建类的实例,比如下面的DateFormatter

/*** 通过构造器创建依赖*/
class DateFormatter @Inject constructor() {@SuppressLint("SimpleDateFormat")private val formatter = SimpleDateFormat("d MMM yyyy HH:mm:ss")fun formatDate(timestamp: Long): String {return formatter.format(Date(timestamp))}
}

再比如Step3中的logger。它与DateFormatter的区别在于它的构造参数是有参数的。那么对于这种情况,我们还需要告诉hilt如何获取LogDao的实例。也就是说如果LogDao能通过构造器构建的话,直接添加@Inject注解就可以了。但是这里的logDao是一个接口,而且它无法手动添加实现类(这个是Android room中的DAO)。所以我们需要使用其他的方式获取

@Singleton
class LoggerLocalDataSource @Inject constructor(private val logDao: LogDao) {...
}

step4-condition2:用 @Provides 提供实例

我们可以在 Hilt 模块中用 @Provides 注释函数,以告诉 Hilt 如何提供无法注入构造函数的 类型。hilt模块也就是用@Module @InstallIn 注释的类的使用。无法通过对构造器添加@Inject注解方式提供实例时通过@Module@InstallIn(指定作用域)来声明提供对象实例的方式。 这个Module是模块,我们需要使用模块向 Hilt 添加绑定,换句话说,就是告诉 Hilt 如何提供不同类型的实例。 在 Hilt 模块中,您需针对无法注入构造函数的类型(如项目中未包含的接口或类)添加绑定。例如 OkHttpClient - 您需要使用其构建器来创建实例。因为这里实际上是提供数据库操作,所以作用域应该是全局的,所以采用的是SingletonComponent。这里还有其他的component

@InstallIn(SingletonComponent::class)
@Module
object DatabaseModule {
//这个可以是个class,但是在 Kotlin 中,只包含 @Provides 函数的模块可以是 object 类。
//这样,提供程序即会得到优化,并几乎可以内联在生成的代码中。/*** 用 @Provides 提供实例。我们可以在 Hilt 模块中用 @Provides 注释函数,* 以告诉 Hilt 如何提供无法注入构造函数的 类型。*/@Providesfun provideLogDao(database: AppDatabase): LogDao {
//return database.logDao()//Hilt 可从上述代码中得知,在提供 LogDao 的实例时需要执行 database.logDao()。//由于我们拥有 AppDatabase 作为传递依赖项,因此我们还需要告诉 Hilt 如何提供这种类型的实例。}//因为我们一直希望 Hilt 提供相同的数据库实例,所以我们用 @Singleton 注释 @Provides provideDatabase 方法。@Provides@Singletonfun provideDatabase(@ApplicationContext context: Context):AppDatabase{return Room.databaseBuilder(context,AppDatabase::class.java,"logging.db").build()}}

step4-condition3:用 @Binds 提供接口。

对于接口我们不能使用构造函数注入。 要告诉 Hilt 对接口使用什么实现,可以在 Hilt 模块内的函数上使用 @Binds 注释。@Binds必须对抽象函数作出注释(因为该函数是抽象的,因此其中不包含任何代码,并且该类也必须是抽象的)。抽象函数的返回类型是我们要为其提供实现的接口(即 AppNavigator)。通过添加具有接口实现类型(即 AppNavigatorImpl)的唯一参数来指定实现。比如在MainActivity中我们依赖的接口

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {@Injectlateinit var navigator: AppNavigator....
}

所以对此我们需要新建module使用@Binds获取,如果类型有作用域,则@Binds 方法必须有作用域注释

//我们的新导航信息(即 AppNavigator)需要特定于 Activity 的信息
//(因为 AppNavigatorImpl 拥有 Activity 作为依赖项)。
// 因此,我们必须将其安装在 Activity 容器中,而不是安装在 Application 容器中,因为这是有关 Activity 的信息所在。
@InstallIn(ActivityComponent::class)
@Module
abstract class NavigationModule {@Bindsabstract fun provideNavigator(impl: AppNavigatorImpl):AppNavigator//参数为具体的实现类,所以要告知hilt如何提供实现类的实例。下面的实现类通过构造函数提供实例
}//======AppNavigatorImpl.ktx========////AppNavigatorImpl 会依赖于 FragmentActivity。由于系统会在 Activity 容器中提供 AppNavigator 实例
// (亦可用于 Fragment 容器和 View 容器,因为 NavigationModule 会安装在 ActivityComponent 中),所以 FragmentActivity 目前可用
class AppNavigatorImpl @Inject constructor(private val activity: FragmentActivity) : AppNavigator {override fun navigateTo(screen: Screens) {val fragment = when (screen) {Screens.BUTTONS -> ButtonsFragment()Screens.LOGS -> LogsFragment()}activity.supportFragmentManager.beginTransaction().replace(R.id.main_container, fragment).addToBackStack(fragment::class.java.canonicalName).commit()}
}

step4-condition4:使用限定符

要告诉 Hilt 如何提供相同类型的不同实现(多个绑定),可以使用限定符。它的定义其实就是注解。

@Qualifier 
annotation class InMemoryLogger 
@Qualifier 
annotation class DatabaseLogger

要比如对log的增删查提供一套基于内存的实现方式,那么定义接口

interface LogDataSource {fun addLog(msg: String)fun getAllLogs(callback: (List<Log>) -> Unit)fun removeLogs()
}

基于Room的实现如下,其实就是开篇提到的实现,只不过实现了该接口

@Singleton
class LoggerLocalDataSource @Inject constructor(private val logDao: LogDao):LogDataSource {private val executorService: ExecutorService = Executors.newFixedThreadPool(4)private val mainThreadHandler by lazy {Handler(Looper.getMainLooper())}override fun addLog(msg: String) {executorService.execute {logDao.insertAll(Log(msg,System.currentTimeMillis()))}}override fun getAllLogs(callback: (List<Log>) -> Unit) {executorService.execute {val logs = logDao.getAll()mainThreadHandler.post { callback(logs) }}}override fun removeLogs() {executorService.execute {logDao.nukeTable()}}
}

基于内存的实现如下

@ActivityScoped
class LoggerInMemoryDataSource @Inject constructor():LogDataSource {private val logs = LinkedList<Log>()override fun addLog(msg: String) {logs.addFirst(Log(msg, System.currentTimeMillis()))}override fun getAllLogs(callback: (List<Log>) -> Unit) {callback(logs)}override fun removeLogs() {logs.clear()}
}

基于上面介绍,使用接口时我们定义实现类如下

@Module
@InstallIn(SingletonComponent::class)
abstract class LoggingDatabaseModule {@DatabaseLogger@Binds@Singletonabstract fun bindDatabaseLogger(impl: LoggerLocalDataSource): LogDataSource
}@Module
@InstallIn(ActivityComponent::class)
abstract class LoggingInMemoryModule {@InMemoryLogger@Binds@ActivityScopedabstract fun bindInMemoryLogger(impl: LoggerInMemoryDataSource): LogDataSource
}

可以看到我们定义了两个module,之所以不是一个module是因为两种实现的作用域不一样。而且在InMemory的@Binds方法上我们还加入了@ActivityScoped,这个是必须加入的,因为实现类中指定了作用域。同理在这儿我们还加入了自定义的注解InMemoryLogger,就是告诉hilt选择那种方式提供实例。如果不加限定符的话会报错。真正使用该接口时如下

class ButtonsFragment : Fragment() {@InMemoryLogger@Inject lateinit var logger: LogDataSource...
}

可以看到与Step3中的区别在于此处变量的类型为接口而不是具体的实现,其次加入了限定符。综上就是Hilt的基本使用

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

相关文章:

Android Jetpack 中Hilt的使用

Hilt 是 Android 的依赖项注入库&#xff0c;可减少在项目中执行手动依赖项注入的样板代码。执行 手动依赖项注入 要求您手动构造每个类及其依赖项&#xff0c;并借助容器重复使用和管理依赖项。 Hilt 通过为项目中的每个 Android 类提供容器并自动管理其生命周期&#xff0c;…...

批量采集的时间管理与优化

在进行大规模数据采集时&#xff0c;如何合理安排和管理爬取任务的时间成为了每个专业程序员需要面对的挑战。本文将分享一些关于批量采集中时间管理和优化方面的实用技巧&#xff0c;帮助你提升爬虫工作效率。 1. 制定明确目标并设置合适频率 首先要明确自己所需获取数据的范…...

uniApp监听左右滑动事件

监听左右滑动事件的步骤 1. 添加需要监听滑动事件的元素 在你的页面中&#xff0c;添加需要监听滑动事件的元素。这可以是一个 view、swiper 或其他组件&#xff0c;取决于你的需求。例如&#xff1a; <template><view class"body" touchstart"touc…...

十八、MySQL添加外键?

1、外键 外键是用来让两张表的数据之间建立联系&#xff0c;从而保证数据的一致性和完整性。 注意&#xff0c;父表被关联的字段类型&#xff0c;必须和子表被关联的字段类型一致。 2、实际操作 &#xff08;1&#xff09;初始化两张表格&#xff1a; 子表&#xff1a; 父…...

图像文件的操作MATLAB基础函数使用

简介 MATLAB中的图像处理工具箱体统了一套全方位的标准算法和图形工具&#xff0c;用于进行图像处理、分析、可视化和算法开发。这里仅仅对常用的基础函数做个使用介绍。 查询图像文件的信息 使用如下函数 imfinfo(filename,fmt) 函数imfinfo返回一个结构体的info&#xff…...

【k8s】Kubernetes版本v1.17.3 kubesphere 3.1.1 默认用户登录失败

1.发帖&#xff1a; Kubernetes版本v1.17.3 kubesphere 3.11 默认用户登录失败 - KubeSphere 开发者社区 2. 问题日志&#xff1a; 2.1问题排查方法 &#xff1a; 用户无法登录 http://192.168.56.100:30880/ 2.2查看用户状态 kubectl get users [rootk8s-node1 ~]# k…...

Mysql加密功能

Mysql加密功能 InnoDB加密功能查询条件问题开启整个数据库加密 InnoDB加密功能 InnoDB是MySQL数据库引擎的一种&#xff0c;它提供了加密存储的功能。具体来说&#xff0c;InnoDB引擎支持以下两种方式的加密存储&#xff1a; 表级加密&#xff1a;InnoDB支持表级加密&#xff…...

redis-win10安装和解决清缓存报错“Error: Protocol error, got “H“ as reply type byte”

win10安装 https://github.com/microsoftarchive/redis/releases 下载最新的zip&#xff0c;解压&#xff0c;把路径加到Path里&#xff0c;每次直接在cmd里 redis-server.exeError: Protocol error, got “H” as reply type byte 这个报错是因为我端口写错了。。无语 D:…...

【视觉检测】电源线圈上的导线弯直与否视觉检测系统软硬件方案

 检测内容 线圈上的导线弯直与否检测系统。  检测要求 检测线圈上的导线有无弯曲&#xff0c;弯曲度由客户自己设定。检测速度5K/8H625PCS/H。  视觉可行性分析 对样品进行了光学实验&#xff0c;并进行图像处理&#xff0c;原则上可以使用机器视觉进行测试测量…...

Java elasticsearch scroll模板实现

一、scroll说明和使用场景 scroll的使用场景&#xff1a;大数据量的检索和操作 scroll顾名思义&#xff0c;就是游标的意思&#xff0c;核心的应用场景就是遍历 elasticsearch中的数据&#xff1b; 通常我们遍历数据采用的是分页&#xff0c;elastcisearch还支持from size的…...

嵌入式基础知识-信息安全与加密

本篇来介绍计算机领域的信息安全以及加密相关基础知识&#xff0c;这些在嵌入式软件开发中也同样会用到。 1 信息安全 1.1 信息安全的基本要素 保密性&#xff1a;确保信息不被泄露给未授权的实体。包括最小授权原则、防暴露、信息加密、物理加密。完整性&#xff1a;保证数…...

TCP的三次握手与四次挥手

首先&#xff0c;源端口号和目标端口号是不可少的&#xff0c;这一点和 UDP 是一样的。如果没有这两个端口号。数据就不知道应该发给哪个应用。 接下来是包的序号。为什么要给包编号呢&#xff1f;当然是为了解决乱序的问题。不编好号怎么确认哪个应该先来&#xff0c;哪个应该…...

【Face Swapping综述】Quick Overview of Face Swap Deep Fakes

【Face Swapping综述】Quick Overview of Face Swap Deep Fakes 0、前言Abstract1. Introduction2. Face Swapping Process2.1. Preprocessing2.2. Identity Extraction2.3. Attributes Extractor2.4. Generator2.5. Postprocessing2.6. Evaluation Methods3. Challenges4. Con…...

etcd选举源码分析和例子

本文主要介绍etcd在分布式多节点服务中如何实现选主。 1、基础知识 在开始之前&#xff0c;先介绍etcd中 Version, Revision, ModRevision, CreateRevision 几个基本概念。 1、version 作用域为key&#xff0c;表示某个key的版本&#xff0c;每个key刚创建的version为1&#…...

Android 网络配置

ip tables 和 ip route 是两个不同的工具&#xff0c;它们在不同的阶段执行不同的功能。ip route 是用来管理和控制路由表的&#xff0c;它决定了数据包应该从哪个网卡或网关发送出去。ip tables 是用来配置、管理和控制网络数据包的过滤、转发和转换的&#xff0c;它根据用户定…...

【网络通信 -- WebRTC】Open WebRTC Toolkit 环境搭建指南

【网络通信 -- WebRTC】Open WebRTC Toolkit -- OWT-Server 编译安装指南 【1】OWT Server 与 Web Demo 视频会议环境搭建 【1.1】编译 OWT Server 安装依赖 ./scripts/installDepsUnattended.sh编译 scripts/build.js -t all --check 注意若不支持硬件加速则采用如下命令 s…...

文件上传漏洞(CVE-2022-30887)

简介 多语言药房管理系统&#xff08;MPMS&#xff09;是用PHP和MySQL开发的&#xff0c;该软件的主要目的是在药房和客户之间提供一套接口&#xff0c;客户是该软件的主要用户。该软件有助于为药房业务创建一个综合数据库&#xff0c;并根据到期、产品等各种参数提供各种报告…...

LeetCode-77-组合

一&#xff1a;题目描述&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 二&#xff1a;示例与提示 示例 1: 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4…...

Oracle中instr,rtrim,XMLPARSE,XMLAGG,GETCLOBVAL函数的使用

1&#xff1a;INSTR()函数 INSTR 是一个字符串函数&#xff0c;用于查找子字符串在源字符串中的位置。 它的语法如下&#xff1a; INSTR(source_string, search_string)source_string 是源字符串&#xff0c;即要在其中进行搜索的字符串。search_string 是要查找的子字符串。…...

java接入apiv3微信小程序支付(以java的eladmin框架为例)

一、需要准备的资料 1.小程序AppID 如&#xff1a;wx2e56f5****** 2.商户号 如&#xff1a;1641****** 3.商户API私钥路径&#xff1a;什么是商户API证书&#xff1f;如何获取商户API证书&#xff1f; 获取文件如下图&#xff1a; 如&#xff1a; 本地路径&#xff1a;E:\Env\e…...

第19节-PhotoShop基础课程-历史记录画笔工具

文章目录 前言1.历史记录画笔工具1.从当前状态创建文档2.创建新快照 2.历史记录艺术画笔工具 前言 任何记录都会被记录下来&#xff0c;并且可以拍快照&#xff0c;从历史中恢复&#xff0c;特别适合艺术创作的孩子 1.历史记录画笔工具 不只是画笔&#xff0c;所有操作记录都…...

MongoDB常用的比较符号和一些功能符号

比较符号 results collection.find({age: {$gt: 20}})功能符号 results collection.find({name: {$regex: ^M.*}})...

网络安全(黑客)技术自学

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防…...

C++ 引用

C 引用 引用变量是一个别名&#xff0c;也就是说&#xff0c;它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量&#xff0c;就可以使用该引用名称或变量名称来指向变量。 C 引用 vs 指针 引用很容易与指针混淆&#xff0c;它们之间有三个主要的不同&#xff1a;…...

9.1.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-道路分割分析

目录 前言1. 道路分割总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-自动驾驶案例项目self-driving-道路分…...

稳定的 Glance 来了,安卓小部件有救了!

稳定的 Glance 来了&#xff0c;安卓小部件有救了&#xff01; 稳定版本的 Glance 终于发布了&#xff0c;来一起看看吧&#xff0c;看看这一路的旅程&#xff0c;看看好用么&#xff0c;再看看如何使用&#xff01; 前世今生 故事发生在两年的一天吧&#xff0c;其实夸张了…...

用友U8与MES系统API接口对接案例分析

企业数字化转型&#xff1a;轻易云数据集成平台助力 U8 ERPMES 系统集成 为什么选择数字化转型&#xff1f; 领导层对企业资源规划&#xff08;ERP&#xff09;的深刻理解促使了数字化转型的启动。采用精确的“N5”滚动计划&#xff0c;为供应商提供充分的预期信息&#xff0c…...

web UI自动化介绍

文章目录 一、web UI自动化介绍1.1 执行UI自动化测试前提1.2 Selenium介绍以及知识点梳理 二、Selenium 学习2.1 基础2.1.1 环境安装与基础使用2.1.2 web浏览器控制2.1.3 常见控件的八大定位方式2.1.3.1 八大定位方式介绍2.1.3.2 NAME、ID定位2.1.3.3 css_selector定位2.1.3.4 …...

小米13Pro/13Ultra刷面具ROOT后激活LSPosed框架微X模块详细教程

喜欢买小米手机&#xff0c;很多是因为小米手机的开放&#xff0c;支持root权限&#xff0c;而ROOT对普通用户来说更多的是刷入DIY模块功能&#xff0c;今天ROM乐园小编就教大家如何使用面具ROOT&#xff0c;实现大家日常情况下非常依赖的微X模块功能&#xff0c;体验微X模块的…...

文盘Rust -- 给程序加个日志 | 京东云技术团队

日志是应用程序的重要组成部分。无论是服务端程序还是客户端程序都需要日志做为错误输出或者业务记录。在这篇文章中&#xff0c;我们结合log4rs聊聊rust 程序中如何使用日志。 log4rs类似java生态中的log4j,使用方式也很相似 log4rs中的基本概念 log4rs 的功能组件也由 appe…...

木屋网站建设/域名注册网站查询

Time Limit: 3 second Memory Limit: 2 MB 【问题描述】 “循环数”指那些不包括数字0的没有重复数字的整数(比如81362)&#xff0c;并且同时具有一个有趣的性质, 就像 这个例子: 如果你从最左边的数字开始 (在这个例子中是8) 数从左边这个数字到右边 (如果数到了最右边,回 到最…...

郑州网站建设开拓者/谷歌推广开户多少费用

HTML DOM 访问访问 HTML DOM - 查找 HTML 元素。访问 HTML 元素(节点)访问 HTML 元素等同于访问节点您能够以不同的方式来访问 HTML 元素&#xff1a;通过使用 getElementById() 方法通过使用 getElementsByTagName() 方法通过使用 getElementsByClassName() 方法getElementByI…...

洛阳建网站公司/学it学费大概多少钱

http://acm.hdu.edu.cn/showproblem.php?pid1212 题目大意&#xff1a; 给你一个长度不超过1000的大数A&#xff0c;还有一个不超过100000的B&#xff0c;让你快速求A % B。 什么&#xff1f;你说用大数的模板&#xff1f;那太慢了&#xff01; 思路&#xff1a; 举个例子&…...

广州最新传染疫情/seo收索引擎优化

大数据 标准库 应用库选择“正确的”数据库通常对于应用程序的成功至关重要。 与考虑供应商的建议或因为已经碰巧已经拥有数据库而使用数据库相比&#xff0c;考虑数据存储的基本目的和需求很有用。 在选择数据库时&#xff0c;这些是最重要的问题&#xff1a; 您希望在应用程…...

网站设计主题/新闻软文自助发布平台

一个人只拥有今生今世是不够的&#xff0c;他还应该拥有一个诗意的世界。——王小波什么是诗意的世界&#xff1f;在现代这个社会中&#xff0c;还有多少人拥有着诗意的世界呢&#xff1f;我觉得在这个世界里&#xff0c;人是放松的、自由的、心灵是愉悦的、又是充满着美好与味…...

企业网站建设参考资料/连云港seo优化

资源介绍资源名称&#xff1a;MSSQL、MySQL、Oracle 三大主流数据库快速上手教程目录&#xff1a;MSSQL、MySQL、Oracle 三大主流数据库快速上手第一章MSSQL、MySQL、Oracle 三大主流数据库快速上手第七章1-4MSSQL、MySQL、Oracle 三大主流数据库快速上手第三章1-5MSSQL、MySQL…...