Android Studio:视图绑定的岁月变迁(2/100)
一、博文导读
本文是基于Android Studio真实项目,通过解析源码了解真实应用场景,写文的视角和读者是同步的,想到看到写到,没有上帝视角。
前期回顾,本文是第二期。
private Unbinder mUnbinder;
只是声明了一个 接口类型 的变量,并没有直接实例化。
二、Unbinder接口
这个 Unbinder
接口通常出现在基于依赖注入框架的 Android 开发中,例如 ButterKnife,用于解绑视图引用。它的主要作用是管理绑定的生命周期,特别是在 Activity
或 Fragment
销毁时释放资源,防止内存泄漏。
上面的方法标记为 @UiThread
,表示它只能在主线程中调用。如果尝试在后台线程调用此方法,则会导致问题。如果你在后台线程调用了这个方法(而没有切换到主线程),Android Studio 可能会发出警告。
unbind
方法:
- 这是一个抽象方法,表示解绑的操作。在 Android 开发中,绑定视图(如使用
ButterKnife.bind()
)后,需要在Activity
或Fragment
销毁时调用unbind
方法,释放视图资源,避免内存泄漏。
EMPTY
对象:
Unbinder.EMPTY
是一个静态的空实现对象,作为默认实现,用于防止空指针异常。- 如果某个绑定没有需要解绑的资源,可以直接返回这个空实现。这样即使调用了
unbind
,也不会引发异常。
Unbinder unbinder = Unbinder.EMPTY; // 初始值为 EMPTY
简单的使用场景:
public class MainActivity extends AppCompatActivity {@BindView(R.id.textView)TextView textView;private Unbinder unbinder;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 绑定视图unbinder = ButterKnife.bind(this);}@Overrideprotected void onDestroy() {super.onDestroy();// 解绑视图,释放资源,防止内存泄漏unbinder.unbind();}
}
在活动页面销毁的时候调用解绑视图,来释放资源。
三、绑定和解绑
先看两种视图绑定的方法对比:
现代官方版本view binding举例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello, View Binding!"android:textSize="18sp" /><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Click Me" />
</LinearLayout>
简单的线性布局,一个文本和一个按钮,其id分别为textView1和button1。下面是活动页面的代码:
public class MainActivity extends AppCompatActivity {// 声明一个视图绑定对象//ActivityMainBinding 是根据你的 XML 文件 activity_main.xml 自动生成的绑定类。private ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//ActivityMainBinding.inflate() 方法会加载 activity_main.xml 布局文件。//getLayoutInflater() 是 Android 提供的工具,用于将 XML 文件转化为对应的视图对象。//结果:binding 变量现在就代表了整个布局,里面包含了所有控件的直接引用。binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());// 使用绑定对象直接访问视图binding.textView1.setText("Welcome to View Binding!");binding.button1.setOnClickListener(v ->Toast.makeText(this, "Button clicked!", Toast.LENGTH_SHORT).show());}@Overrideprotected void onDestroy() {super.onDestroy();// 防止内存泄漏binding = null;}
}
工作原理:
- 直接生成绑定类:视图绑定会为每个布局文件自动生成一个对应的绑定类,比如
activity_main.xml
会生成ActivityMainBinding
。 - 通过绑定类访问控件:直接通过
binding
对象访问控件,无需手动查找视图。 - 视图绑定的优势是直接通过
binding
对象访问控件,类型安全且简洁高效,不再需要findViewById
。
以下是使用 ButterKnife 所需的完整配置,包括依赖、代码示例以及运行步骤:
1. 添加 ButterKnife 的依赖
在你的 build.gradle
文件中,添加以下依赖:
项目根目录的 build.gradle
确保添加 ButterKnife 的 Maven 仓库:
allprojects {repositories {google()mavenCentral()}
}
模块的 build.gradle
在 dependencies
中添加 ButterKnife 的依赖:
dependencies {// 添加 ButterKnife 的核心库implementation 'com.jakewharton:butterknife:10.2.3'// 添加 ButterKnife 的注解处理器(用于生成代码)annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
}
xml界面不变,创建 MainActivity.java
并添加以下代码:
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;public class MainActivity extends AppCompatActivity {// 使用 @BindView 注解绑定布局中的控件@BindView(R.id.textView) TextView textView;@BindView(R.id.button) Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 初始化 ButterKnifeButterKnife.bind(this);// 设置默认文本textView.setText("Welcome to ButterKnife!");}// 使用 @OnClick 注解绑定点击事件@OnClick(R.id.button)void onButtonClick() {Toast.makeText(this, "Button clicked!", Toast.LENGTH_SHORT).show();}
}
老版本的试图绑定,还是很麻烦的。
相关文章:

Android Studio:视图绑定的岁月变迁(2/100)
一、博文导读 本文是基于Android Studio真实项目,通过解析源码了解真实应用场景,写文的视角和读者是同步的,想到看到写到,没有上帝视角。 前期回顾,本文是第二期。 private Unbinder mUnbinder; 只是声明了一个 接口…...

LabVIEW春节快乐
尊敬的LabVIEW开发者与用户朋友们: 灵蛇舞动辞旧岁,春风送暖贺新年!值此癸巳蛇年新春佳节来临之际,向每一位深耕LabVIEW开发领域的伙伴致以最诚挚的祝福:愿您与家人在新的一年里平安顺遂、阖家幸福,事业如…...

rewrite规则
NGINX 中 rewrite最后的标记含义: flag标记有: last 相当于Apache里的[L]标记,表示完成rewrite,匹配完,再向下匹配。地址栏会显示跳转后的地址 break 终止匹配, 不再匹配后面的rewrite规则,地址栏会显示跳…...

Android车机DIY开发之学习篇(七)NDK交叉工具构建
Android车机DIY开发之学习篇(七)NDK交叉工具构建 1.ubuntu安装GCC sudo apt-get update sudo apt-get install gcc g sudo gcc --version sudo g --version 2.测试GCC VSCODE中新建Hello.c编译 #include <stdio.h> int main(void) { printf(“Hello, this is a progr…...

【初/高中生讲机器学习】0. 本专栏 “食用” 指南——写在一周年之际⭐
创建时间:2025-01-27 首发时间:2025-01-29 最后编辑时间:2025-01-29 作者:Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏,很高兴遇见你~ 我是 Geeker_LStar,一名高一学生,热爱计…...

虚幻基础11:坐标计算旋转计算
能帮到你的话,就给个赞吧 😘 文章目录 坐标line startget actor rotationget forward vector 旋转计算 坐标 ue中通常使用向量计算坐标。 line start 起始坐标点。 get actor rotation 获取旋转值: 当前角色朝向 get forward vector 获…...

Rust:Rhai脚本编程示例
当然,以下是一个简单的Rhai脚本编程示例,展示了如何在Rust中使用Rhai执行脚本。 首先,你需要确保你的Rust项目中包含了rhai库。你可以在你的Cargo.toml文件中添加以下依赖项: [dependencies] rhai "0.19" # 请检查最…...

关于el-table翻页后序号列递增的组件封装
需求说明: 项目中经常会用到的一个场景,表格第一列显示序号(1、2、3...),但是在翻页后要递增显示序号,例如10、11、12(假设一页显示10条数据),针对这种情况,封…...

【深度学习】softmax回归
softmax回归 回归可以用于预测多少的问题。 比如预测房屋被售出价格,或者棒球队可能获得的胜场数,又或者患者住院的天数。 事实上,我们也对分类问题感兴趣:不是问“多少”,而是问“哪一个”: 某个电子邮…...

设计模式-建造者模式、原型模式
目录 建造者模式 定义 类图 优缺点 角色 建造者模式和工厂模式比较 使用案例 原型模式 定义 类图 优缺点 应用场景 应用类型 浅克隆 深克隆 建造者模式 定义 将一个复杂的对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,…...

【Redis】List 类型的介绍和常用命令
1. 介绍 Redis 中的 list 相当于顺序表,并且内部更接近于“双端队列”,所以也支持头插和尾插的操作,可以当做队列或者栈来使用,同时也存在下标的概念,不过和 Java 中的下标不同,Redis 支持负数下标&#x…...

三个不推荐使用的线程池
线程池的种类 其实看似这么多的线程池,都离不开ThreadPoolExecutor去创建,只不过他们是简化一些参数 newFixedThreadPool 里面全是核心线程 有资源耗尽的风险,任务队列最大长度为Integer.MAX_VALUE,可能会堆积大量的请求ÿ…...

mybatis(78/134)
前天学了很多,关于java的反射机制,其实跳过了new对象,然后底层生成了字节码,创建了对应的编码。手搓了一遍源码,还是比较复杂的。 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE …...

Progressive Pretext Task Learning for Human Trajectory Prediction | 文献翻译
祥龙回首留胜景,金蛇起舞贺新程。 概述 行人轨迹预测是一项旨在预测行人未来位置的任务,它通常涵盖了从短期到长期的整个时间范围内的轨迹。然而,现有的研究试图通过单一、统一的训练范式来解决整个轨迹预测问题,往往忽视了行人轨…...

54.数字翻译成字符串的可能性|Marscode AI刷题
1.题目 问题描述 小M获得了一个任务,需要将数字翻译成字符串。翻译规则是:0对应"a",1对应"b",依此类推直到25对应"z"。一个数字可能有多种翻译方法。小M需要一个程序来计算一个数字有多少种不同的…...

【数据结构】_链表经典算法OJ(力扣版)
目录 1. 移除链表元素 1.1 题目描述及链接 1.2 解题思路 1.3 程序 2. 反转链表 2.1 题目描述及链接 2.2 解题思路 2.3 程序 3. 链表的中间结点 3.1 题目描述及链接 3.2 解题思路 3.3 程序 1. 移除链表元素 1.1 题目描述及链接 原题链接:203. 移除链表…...

【Linux】统计文本中每行指定位置出现的字符串的次数
统计文本中每行指定位置出现的字符串的次数 假定情景 某些项目,会把某个特定事件记录到Log中并且落盘(保持到硬盘)。基于落盘后的日志,要统计这些日志里产生该特定事件的次数 统计脚本 可以写一个sh脚本,来解析某个…...

【赵渝强老师】K8s中Pod探针的ExecAction
在K8s集群中,当Pod处于运行状态时,kubelet通过使用探针(Probe)对容器的健康状态执行检查和诊断。K8s支持三种不同类型的探针,分别是:livenessProbe(存活探针)、readinessProbe&#…...

商品信息管理自动化测试
目录 前言 一、思维导图 二、代码编写 1.在pom.xml文件中添加相关依赖 2.自动化代码编写 三、代码测试 小结 前言 1. 针对商品信息管理项目进行测试,商品信息管理项目主要有商品列表页、部门列表页、员工列表页,主要功能:对商品信息的…...

Redis实战(黑马点评)——redis存储地理信息、位图、HyperLogLog 用法
Redis存储geo数据类型基本介绍 geo 就是 geolocation 的简写形式,代表地理坐标。redis 在 3.2 版本中加入了对 geo 的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据。常见的命令有: geoadd:添加一个地理空…...

判断1到100之间有多少个素数,并输出所有的素数。
def is_prime(num): #判断一个数是否素数if num<1:return False #因为1和负数都不是素数for i in range(2,int(num**0.5)1): #从2开始到根号num的整数结束,因为一个数num不是素数,那么把必定有一个小于或等于根号num的因素if num%i0:return False #如…...

JAVA:利用 Content Negotiation 实现多样式响应格式的技术指南
1、简述 Content Negotiation(内容协商) 是 RESTful 服务的重要特性,允许客户端和服务器根据请求的不同特性动态选择适合的响应格式。它是一种在 HTTP 协议中实现的机制,通过它,服务器能够根据客户端需求返回适合的内…...

layui Table单元格编辑支持Enter键换行,包括下拉框单元格
layui Table表格编辑支持Enter键换行 可编辑单元格 $(".layui-table td").keydown(function (e) {// console.log("111",e);var index $(this).index(),tr $(this).parent(tr),isKeydown (event.type "keydown");if (e.code "Enter&q…...

Swoole的MySQL连接池实现
在Swoole中实现MySQL连接池可以提高数据库连接的复用率,减少频繁创建和销毁连接所带来的开销。以下是一个简单的Swoole MySQL连接池的实现示例: 首先,确保你已经安装了Swoole扩展和PDO_MySQL扩展(或mysqli,但在这个示…...

无人机红外热成像:应急消防的“透视眼”
无人机红外热成像:应急消防的“透视眼” 亲爱的小伙伴们,每年一到夏天,应急消防的战士们就像上紧了发条的闹钟,时刻准备应对各种灾害。炎热天气让火灾隐患“蹭蹭”往上涨,南北各地还有防洪救灾、台风、泥石流等灾害轮…...

【redis】Redis操作String类型key的发生了什么?
关于Redis操作(添加、删除、修改、查询)String类型key的完整过程,包括引用源码数据、时序图、磁盘IO读写、数据长度限制和故障处理机制。 数据结构 Redis对象(robj) typedef struct redisObject {unsigned type:4; …...

hdfs之读写流程
写入流程: 客户端Client想将文件a.txt上传至hdfs,首先向Namenode发送请求进行权限校验,Namenode通过后会计算出来三个节点,并将这三个节点告知客户端,客户端将输入进行切割成块,一个一个的块进行传输&…...

研发的立足之本到底是啥?
0 你的问题,我知道! 本文深入T型图“竖线”的立足之本:专业技术 技术赋能业务能力。研发在学习投入精力最多,也误区最多。 某粉丝感发展遇到瓶颈,项目都会做,但觉无提升,想跳槽。于是&#x…...

Baklib揭示内容中台与人工智能技术的创新协同效应
内容概要 在当今信息爆炸的时代,内容的高效生产与分发已成为各行业竞争的关键。内容中台与人工智能技术的结合,为企业提供了一种新颖的解决方案,使得内容创造的流程更加智能化和高效化。 内容中台作为信息流动的核心,能够集中管…...

智慧消防营区一体化安全管控 2024 年度深度剖析与展望
在 2024 年,智慧消防营区一体化安全管控领域取得了令人瞩目的进展,成为保障营区安全稳定运行的关键力量。这一年,行业在政策驱动、技术创新应用、实践成果及合作交流等方面呈现出多元且深刻的发展态势,同时也面临着一系列亟待解决…...