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

Android Studio:视图绑定的岁月变迁(2/100)

一、博文导读

        本文是基于Android  Studio真实项目,通过解析源码了解真实应用场景,写文的视角和读者是同步的,想到看到写到,没有上帝视角。

前期回顾,本文是第二期。

private Unbinder mUnbinder; 只是声明了一个 接口类型 的变量,并没有直接实例化。 

 二、Unbinder接口

        这个 Unbinder 接口通常出现在基于依赖注入框架的 Android 开发中,例如 ButterKnife,用于解绑视图引用。它的主要作用是管理绑定的生命周期,特别是在 ActivityFragment 销毁时释放资源,防止内存泄漏。

        上面的方法标记为 @UiThread,表示它只能在主线程中调用。如果尝试在后台线程调用此方法,则会导致问题。如果你在后台线程调用了这个方法(而没有切换到主线程),Android Studio 可能会发出警告。

unbind 方法

  • 这是一个抽象方法,表示解绑的操作。在 Android 开发中,绑定视图(如使用 ButterKnife.bind())后,需要在 ActivityFragment 销毁时调用 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真实项目&#xff0c;通过解析源码了解真实应用场景&#xff0c;写文的视角和读者是同步的&#xff0c;想到看到写到&#xff0c;没有上帝视角。 前期回顾&#xff0c;本文是第二期。 private Unbinder mUnbinder; 只是声明了一个 接口…...

私有包上传maven私有仓库nexus-2.9.2

一、上传 二、获取相应文件 三、最后修改自己的pom文件...

Qt监控系统辅屏预览/可以同时打开4个屏幕预览/支持5x64通道预览/onvif和rtsp接入/性能好

一、前言说明 在监控系统中&#xff0c;一般主界面肯定带了多个通道比如16/64通道的画面预览&#xff0c;随着电脑性能的增强和多屏幕的发展&#xff0c;再加上现在监控摄像头数量的增加&#xff0c;越来越多的用户希望在不同的屏幕预览不同的实时画面&#xff0c;一个办法是打…...

Vue.js 路由懒加载

Vue.js 路由懒加载 在 Vue.js 开发中&#xff0c;随着应用规模的扩大&#xff0c;打包后的 JavaScript 文件可能会变得相当庞大&#xff0c;影响页面的加载速度和性能。为了解决这个问题&#xff0c;Vue Router 提供了路由懒加载功能&#xff0c;可以将不同路由对应的组件分割…...

HBase的原理

一、什么是HBase HBase是一个分布式&#xff0c;版本化&#xff0c;面向列的数据库&#xff0c;依赖Hadoop和Zookeeper &#xff08;1&#xff09;HBase的优点 提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统 (2) HBase 表的特性 Region包含多行 列族包含多…...

Python “字典” 实战案例:5个项目开发实例

Python “字典” 实战案例&#xff1a;5个项目开发实例 内容摘要 本文包括 5 个使用 Python 字典的综合应用实例。具体是&#xff1a; 电影推荐系统配置文件解析器选票统计与排序电话黄页管理系统缓存系统&#xff08;LRU 缓存&#xff09; 以上每一个实例均有完整的程序代…...

(DM)达梦数据库基本操作(持续更新)

1、连接达梦数据库 ./disql 用户明/"密码"IP端口或者域名 2、进入某个模式&#xff08;数据库,因达梦数据库没有库的概念&#xff0c;只有模式&#xff0c;可以将模式等同于库&#xff09; set schema 库名&#xff1b; 3、查表结构&#xff1b; SELECT COLUMN_NAM…...

LabVIEW心音心电同步采集与实时播放

开发了一个基于LabVIEW开发的心音心电同步采集与实时播放系统。该系统可以同时采集心音和心电信号&#xff0c;并通过LabVIEW的高级功能实现这些信号的实时显示和播放。系统提升心脏疾病诊断的准确性和效率&#xff0c;使医生能够在观察心音图的同时进行听诊。 ​ 项目背景 心…...

[创业之路-268]:《创业讨论会》- 个人思维 -> 团队思维 -> 管理思维 -> 领导者思维 -> 老板思维->企业家思维->政治家思维的演进路径

目录 一、演进路径 二、老板与企业家的区别 一、演进路径 这个演进路径描述了一个个体从个人思考模式逐渐发展到领导和管理整个组织或企业的思考模式的过程。下面是对每个阶段的简要解释&#xff1a; 这个演进路径并不是线性的&#xff0c;也不是每个人都会经历所有阶段。然…...

单片机基础模块学习——数码管(二)

一、数码管模块代码 这部分包括将数码管想要显示的字符转换成对应段码的函数&#xff0c;另外还包括数码管显示函数 值得注意的是对于小数点和不显示部分的处理方式 由于小数点没有单独占一位&#xff0c;所以这里用到了两个变量i,j用于跳过小数点导致的占据其他字符显示在数…...

深入解析ncnn::Net类——高效部署神经网络的核心组件

最近在学习ncnn推理框架&#xff0c;下面整理了ncnn::Net 的使用方法。 在移动端和嵌入式设备上进行高效的神经网络推理&#xff0c;要求框架具备轻量化、高性能以及灵活的扩展能力。作为腾讯开源的高性能神经网络推理框架&#xff0c;ncnn在这些方面表现出色。而在ncnn的核心…...

前端【8】HTML+CSS+javascript实战项目----实现一个简单的待办事项列表 (To-Do List)

目录 一、功能需求 二、 HTML 三、CSS 四、js 1、绑定事件与初始设置 2.、绑定事项 &#xff08;1&#xff09;添加操作&#xff1a; &#xff08;2&#xff09;完成操作 &#xff08;3&#xff09;删除操作 &#xff08;4&#xff09;修改操作 3、完整js代码 总结…...

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<1>

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。 这一节我们来学习指针的相关知识&#xff0c;学习内存和地址&#xff0c;指针变量和地址&#xff0c;包…...

向量和矩阵算法笔记

向量和矩阵算法笔记 Ps:因为本人实力有限,有一部分可能不太详细,若有补充评论区回复,QWQ 向量 向量的定义 首先,因为我刚刚学到高中的向量,对向量的看法呢就是一条有长度和方向的线,不过这在数学上的定义其实是不对,甚至跟我看的差别其实有点大,真正的定义就是数域…...

Nginx配置中的常见错误:SSL参数解析

摘要 在高版本的Nginx中&#xff0c;用户可能会遇到unknown directive “ssl”的错误提示。这是因为旧版本中使用的ssl on参数已被弃用。正确的配置SSL加密的方法是在listen指令中添加ssl参数。这一改动简化了配置流程&#xff0c;提高了安全性。用户应更新配置文件以适应新版本…...

積分方程與簡單的泛函分析6.有連續對稱核的弗雷德霍姆積分算子的特徵值

1)def弗雷德霍姆算子的核函數定義 定义: 设 是定义在矩形区域 上的函数。 若满足以下条件,则称 为弗雷德霍姆算子的核函数: 实值性: 是实值函数,即对于任意的 ,。 这是因为在许多实际的物理和数学问题中,所涉及的量往往是实数值,例如在积分方程描述的物理模型中,…...

AI编程工具使用技巧:在Visual Studio Code中高效利用阿里云通义灵码

AI编程工具使用技巧&#xff1a;在Visual Studio Code中高效利用阿里云通义灵码 前言一、通义灵码介绍1.1 通义灵码简介1.2 主要功能1.3 版本选择1.4 支持环境 二、Visual Studio Code介绍1.1 VS Code简介1.2 主要特点 三、安装VsCode3.1下载VsCode3.2.安装VsCode3.3 打开VsCod…...

Yii框架中的扩展:如何使用外部库

在Yii框架中&#xff0c;扩展功能的一种常见且有效的方式是使用外部库。这些外部库可以帮助开发者实现特定的功能&#xff0c;如调用第三方API、处理图片、生成PDF文件或发送邮件等。以下是使用外部库扩展Yii框架的详细步骤&#xff1a; 一、安装外部库 使用Composer&#xff…...

kettle与Springboot的集成方法,完整支持大数据组件

目录 概要整体架构流程技术名词解释技术细节小结 概要 在现代数据处理和ETL&#xff08;提取、转换、加载&#xff09;流程中&#xff0c;Kettle&#xff08;Pentaho Data Integration, PDI&#xff09;作为一种强大的开源ETL工具&#xff0c;被广泛应用于各种数据处理场景。…...

GitHub Actions 使用需谨慎:深度剖析其痛点与替代方案

在持续集成与持续部署&#xff08;CI/CD&#xff09;领域&#xff0c;GitHub Actions 曾是众多开发者的热门选择&#xff0c;但如今&#xff0c;其弊端逐渐显现&#xff0c;让不少人在使用前不得不深思熟虑。 团队由大约 15 名工程师组成&#xff0c;采用基于主干的开发方式&am…...

<iframe>标签和定时调用函数setInterval

iframe 标签和定时调用函数 setInterval 问题描述&#xff1a;解决方法&#xff1a; 问题描述&#xff1a; 今天遇到一个前端问题&#xff0c;在浏览器页面上传Excel文件后&#xff0c;然后点击导入按钮&#xff0c;经后端Java类读取文件内容校验后&#xff0c;将校验结果返回…...

MYSQL学习笔记(六):聚合函数、sql语句执行原理简要分析

前言&#xff1a; 学习和使用数据库可以说是程序员必须具备能力&#xff0c;这里将更新关于MYSQL的使用讲解&#xff0c;大概应该会更新30篇&#xff0c;涵盖入门、进阶、高级(一些原理分析);这一篇是内容较少&#xff0c;主要讲解&#xff1a;聚合函数和简要介绍sql语句执行过…...

Qt——界面优化

一.QSS 1.背景 在网页前端开发领域中&#xff0c; CSS 是⼀个至关重要的部分。 描述了⼀个网页的 "样式"。 从而起到对网页美化的作用。 所谓样式&#xff0c;包括不限于大小&#xff0c;位置&#xff0c;颜色&#xff0c;背景&#xff0c;间距&#xff0c;字体等等…...

MySQL 数据库常见字段类型大全及详细解析

在工作期间会遇到数据库建表的业务&#xff0c;经常会使用复制粘帖等操作&#xff0c;而不清楚数据库的字段类型。本文记录了 MySQL 数据库常见字段类型&#xff0c;根据不同的数据需求&#xff0c;可以选择不同的字段类型来存储数据。 文章目录 一、整数类型1、TINYINT&#x…...

MATLAB 工具库的使用说明和案例示例

以下是一些常见的 MATLAB 工具库的使用说明和案例示例&#xff1a; 信号处理工具箱&#xff08;Signal Processing Toolbox&#xff09;&#xff1a; 使用说明&#xff1a;提供了用于生成、测量、变换、过滤和可视化信号的函数和应用程序。包括重新采样、平滑、同步信号、设计…...

对于Docker的初步了解

简介与概述 1.不需要安装环境&#xff0c;工具包包含了环境&#xff08;jdk等&#xff09; 2.打包好&#xff0c;“一次封装&#xff0c;到处运行” 3.跨平台&#xff0c;docker容器在任何操作系统上都是一致的&#xff0c;这就是实现跨平台跨服务器。只需要一次配置好环境&…...

java基础学习——jdbc基础知识详细介绍

引言 数据的存储 我们在开发 java 程序时&#xff0c;数据都是存储在内存中的&#xff0c;属于临时存储&#xff0c;当程序停止或重启时&#xff0c;内存中的数据就会丢失&#xff0c;我们为了解决数据的长期存储问题&#xff0c;有以下解决方案&#xff1a; 通过 IO流书记&…...

第20篇:Python 开发进阶:使用Django进行Web开发详解

第20篇&#xff1a;使用Django进行Web开发 内容简介 在上一篇文章中&#xff0c;我们深入探讨了Flask框架的高级功能&#xff0c;并通过构建一个博客系统展示了其实际应用。本篇文章将转向Django&#xff0c;另一个功能强大且广泛使用的Python Web框架。我们将介绍Django的核…...

CukeTest使用 | 1 CukeTest是什么?如何下载安装?

CukeTest使用 | 1 CukeTest是什么&#xff1f;如何下载安装&#xff1f; 1 CukeTest是什么&#xff1f;2 关于开发者3 CukeTest有哪些特性&#xff1f;4 都支持哪些自动化技术类型&#xff1f;5 版本区别6 下载安装 特殊说明&#xff1a;学习内容主要来自官网的教程、以及网上公…...

An OpenGL Toolbox

3.An OpenGL Toolbox 声明&#xff1a;该代码来自&#xff1a;Computer Graphics Through OpenGL From Theory to Experiments&#xff0c;仅用作学习参考 3.1 Vertex Arrays and Their Drawing Commands 顶点数组及其绘制命令&#xff1a;将几何数据存储在一个位置&#xff0c…...