android中相近方法对比

1️⃣、getDimension() vs ``getDimensionPixelSize() vs getDimensionPixelOffset()

在 Android 开发中,getDimension()getDimensionPixelSize()getDimensionPixelOffset() 都是 Resources 类中用于获取尺寸资源的方法,主要用于将 dpsp 等单位转换为像素(px),但它们的返回值和用途有所不同:

  1. getDimension(int id)
  • 返回值float 类型,返回转换后的像素值(包含小数部分)。
  • 转换逻辑 :根据当前设备的屏幕密度,将资源中定义的 dp/sp 等单位转换为精确的像素值(可能带有小数)。
  • 适用场景:需要精确像素值(如动画中的细微位置计算、绘制自定义 View 时的坐标定位等)。
java 复制代码
// 示例:获取 res/values/dimens.xml 中定义的尺寸
float dimension = getResources().getDimension(R.dimen.margin);
  1. getDimensionPixelSize(int id)
  • 返回值int 类型,返回转换后四舍五入的像素值(整数)。
  • 转换逻辑 :先执行与 getDimension() 相同的转换,得到 float 像素值,再通过四舍五入(Math.round())取整。
  • 适用场景 :大多数 UI 布局场景(如设置 View 的宽高、边距等),因为 View 的尺寸属性(layout_width 等)只接受整数像素。
java 复制代码
int pixelSize = getResources().getDimensionPixelSize(R.dimen.button_height);
view.setHeight(pixelSize); // View 高度需整数像素
  1. getDimensionPixelOffset(int id)
  • 返回值int 类型,返回转换后截断小数的像素值(整数,相当于 (int)floatValue)。

  • 转换逻辑 :先执行与 getDimension() 相同的转换,得到 float 像素值,再直接截断小数部分(取整数部分,不四舍五入)。

  • 适用场景:需要严格向下取整的场景(如避免因四舍五入导致的布局溢出)。

    int pixelOffset = getResources().getDimensionPixelOffset(R.dimen.padding);
    view.setPadding(pixelOffset, 0, 0, 0);

对比总结

方法 返回类型 转换方式 典型用途
getDimension() float 精确转换(保留小数) 动画、绘制等需要高精度的场景
getDimensionPixelSize() int 四舍五入取整 大多数 UI 布局(宽高、边距等)
getDimensionPixelOffset() int 截断小数取整 需严格向下取整的布局场景

注意事项

  • 这三个方法的输入都是尺寸资源 ID(定义在 res/values/dimens.xml 中,单位可以是 dpsppx 等)。
  • 对于 px 单位的资源,三者返回值一致(因为无需转换,直接返回整数或浮点形式的像素值)。
  • 推荐优先使用 getDimensionPixelSize() 处理 UI 布局,它的四舍五入逻辑更符合人眼对尺寸的感知。

在 Android 开发中,除了 getDimension()getDimensionPixelSize()getDimensionPixelOffset(),还有其他获取尺寸资源的方法,适用于不同场景

  1. getFraction()
  • 功能:获取资源中定义的分数值,可根据参考尺寸计算实际像素。

  • 适用场景:需按比例计算尺寸时,比如根据父容器大小设置子 View 尺寸。

  • 使用示例

    xml

    XML 复制代码
    <!-- 在 res/values/dimens.xml 中定义 -->
    <fraction name="half_width">50%p</fraction> <!-- 相对于父容器的50% -->

    使用

    java 复制代码
    // 参数:资源ID、基准宽度、基准高度(单位px),返回计算后的float值
    float halfWidth = getResources().getFraction(R.fraction.half_width, parentWidth, parentHeight);
  1. getInteger()
  • 功能:获取资源中定义的整数类型尺寸或数值。

  • 适用场景:获取整数配置,如网格列数、最大显示数量等。

  • 使用示例

    xml

    XML 复制代码
    <!-- 在 res/values/integers.xml 中定义 -->
    <integer name="grid_columns">3</integer>

    使用

    java 复制代码
    int columns = getResources().getInteger(R.integer.grid_columns);
  1. getDimensionForSize()(API 29+)
  • 功能 :专为获取 View 尺寸设计,返回值为 int,效果类似 getDimensionPixelSize()

  • 特点:在 API 29 及以上版本中,推荐用于 View 尺寸设置,更符合布局场景。

  • 使用示例

    java 复制代码
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        int size = getResources().getDimensionForSize(R.dimen.view_size);
        view.setLayoutParams(new ViewGroup.LayoutParams(size, size));
    }
  1. TypedValue 配合 resolveDimension()
  • 功能:手动解析尺寸资源,获取原始值和单位,适合需要自定义转换逻辑的场景。

  • 使用示例

    java 复制代码
    TypedValue typedValue = new TypedValue();
    getResources().getValue(R.dimen.margin, typedValue, true);
    // 获取原始值和单位(如 typedValue.data 为值,typedValue.unit 为单位)
    float value = typedValue.getDimension(getResources().getDisplayMetrics());
  1. 直接从 TypedArray 中获取
  • 功能 :在自定义 View 的 obtainStyledAttributes() 中获取布局文件中定义的尺寸属性。

  • 适用场景:自定义 View 解析自定义属性时使用。

  • 使用示例

    java 复制代码
    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
    // 类似 getDimensionPixelSize()
    int customSize = ta.getDimensionPixelSize(R.styleable.MyCustomView_customSize, 0);
    ta.recycle();

总结

这些方法适用场景各有不同:

  • 比例计算用 getFraction()
  • 整数配置用 getInteger()
  • 高版本 View 尺寸设置用 getDimensionForSize()
  • 自定义解析逻辑用 TypedValue
  • 自定义 View 属性解析用 TypedArray 相关方法。

2️⃣、View 测量与布局相关的临近方法

这些方法用于 View 的尺寸计算和位置确定,常配套使用:

方法 功能 关联方法 区别与联系
measure(int widthMeasureSpec, int heightMeasureSpec) 测量 View 所需尺寸 getMeasuredWidth() getMeasuredHeight() measure() 触发测量,后两者获取测量结果(测量尺寸)
layout(int l, int t, int r, int b) 确定 View 在父容器中的位置 getLeft()/getTop() getRight()/getBottom() layout() 确定位置,后四者获取相对父容器的坐标
onMeasure(int, int) onLayout(boolean, int, int, int, int) 自定义 View 时重写的测量和布局逻辑 setMeasuredDimension() 前者需调用 setMeasuredDimension() 保存测量结果,后者用于子 View 布局
getWidth() getHeight() 获取 View 最终显示的宽高 getMeasuredWidth() getMeasuredHeight() 前者是布局后实际尺寸,后者是测量尺寸,多数情况相等,但存在测量≠布局的场景(如父容器强制限制)

3️⃣、资源获取相关的临近方法

用于获取各类资源,因返回值或用途不同而区分:

方法 功能 关联方法 区别与联系
getResources().getString(int id) 获取字符串资源 getString(int id, Object... formatArgs) 后者支持格式化(如 %s 占位符替换)
getDrawable(int id) 获取 Drawable 资源 getDrawable(int id, Theme theme) 后者可指定主题(API 21+),适配不同主题下的资源
getColor(int id) 获取颜色值 getColor(int id, Theme theme) 类似 Drawable,后者支持主题(API 23+)
getDimension(...) 系列 获取尺寸资源(见前文) getFraction(...) getInteger(...) 同属资源获取,但处理不同类型(尺寸、分数、整数)

4️⃣、Intent 跳转相关的临近方法

用于 Activity 跳转和数据传递,功能互补:

方法 功能 关联方法 区别与联系
startActivity(Intent) 启动新 Activity startActivityForResult(Intent, int) 后者期望从新 Activity 获取返回数据(已被 Activity Result API 替代)
startService(Intent) 启动服务 bindService(Intent, ServiceConnection, int) 前者启动独立服务,后者绑定服务并获取交互接口
putExtra(String, ...) 向 Intent 中添加数据 getExtra(String) 前者存数据,后者取数据,配套用于组件间通信

5️⃣、SharedPreferences 操作相关的临近方法

用于轻量级数据存储,读写逻辑对应:

方法 功能 关联方法 区别与联系
edit() 获取编辑器对象 commit() apply() edit() 开启编辑,后两者提交修改(commit() 同步返回结果,apply() 异步高效)
getString(String, String) 获取 String 类型数据 putString(String, String) 读写对应,其他类型(int/boolean 等)也有类似成对方法

6️⃣、线程与 Handler 相关的临近方法

用于线程间通信,控制任务执行时机:

方法 功能 关联方法 区别与联系
post(Runnable) 向 Handler 所在线程(通常主线程)提交任务 postDelayed(Runnable, long) 后者延迟执行任务,均用于切换到主线程更新 UI
sendMessage(Message) 发送消息到消息队列 handleMessage(Message) 前者发消息,后者在 Handler 中处理消息,是消息机制的核心配对方法
runOnUiThread(Runnable) 在主线程执行任务 post(Runnable)(Handler) 两者功能类似,runOnUiThread 是 Activity 的便捷方法,内部依赖 Handler

分析临近方法的意义

  1. 避免误用 :例如区分 getMeasuredWidth()getWidth(),避免在 onMeasure() 中使用 getWidth()(此时布局未完成,值为 0)。
  2. 理解设计逻辑 :如 commit()apply() 的区别,体现了 Android 对性能(异步)和可靠性(同步返回结果)的平衡。
  3. 优化代码 :例如用 apply() 替代 commit() 提升 SharedPreferences 写入性能,用 Activity Result API 替代过时的 startActivityForResult()

7️⃣、startActivityForResult() vs Activity Result API

功能 :均用于从启动的 Activity 获取返回数据
区别

维度 startActivityForResult()(已过时) Activity Result API(推荐)
用法 重写 onActivityResult() 处理返回数据 注册 ActivityResultCallback 回调
生命周期关联 依赖 Activity 生命周期,易因配置变化丢失数据 与生命周期解耦,自动处理配置变化
类型安全 需手动解析数据,易出错 支持泛型,编译期检查类型
示例代码 startActivityForResult(intent, REQUEST_CODE); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { ... } ActivityResultLauncher launcher = registerForActivityResult(...); launcher.launch(intent);<br>

8️⃣、commit() vs apply()(SharedPreferences)

功能 :提交 SharedPreferences 的编辑内容
区别

维度 commit() apply()(推荐)
执行方式 同步执行,阻塞当前线程 异步执行,提交到主线程队列
返回值 boolean,表示提交是否成功 无返回值
适用场景 需要知道提交结果的场景(极少) 大多数场景,性能更优
注意事项 主线程调用可能导致 ANR 不会阻塞线程,但数据未持久化时进程被杀会丢失

9️⃣、getWidth() vs getMeasuredWidth()

功能 :获取 View 的宽度
区别

维度 getWidth() getMeasuredWidth()
时机 布局(layout())完成后有效 测量(measure())完成后有效
数值来源 实际显示宽度(right - left 测量得出的宽度(setMeasuredDimension() 设置)
典型场景 布局完成后获取最终尺寸 自定义 View 测量阶段获取测量结果
特殊情况 可能被父容器强制修改(如超出父布局) 反映 View 自身期望的尺寸

🔟、invalidate() vs postInvalidate()

功能 :触发 View 重绘
区别

维度 invalidate() postInvalidate()
调用线程 必须在主线程调用 可在子线程调用
实现原理 直接触发重绘流程 内部通过 Handler 切换到主线程调用 invalidate()
适用场景 主线程中更新 UI 后重绘 子线程中计算数据后触发重绘

🔟1️⃣、dp vs sp vs px

功能 :定义尺寸单位
区别

维度 dp(density-independent pixel) sp(scale-independent pixel) px(pixel)
适配性 随屏幕密度变化,保证不同设备显示比例一致 除屏幕密度外,还受系统字体大小影响 固定像素,不适配
适用场景 布局尺寸(宽高、边距等) 文字大小 极少使用(如精确像素绘制)

🔟2️⃣、View.setVisibility(View.GONE) vs View.setVisibility(View.INVISIBLE)

功能 :控制 View 的可见性
区别

维度 GONE INVISIBLE
空间占用 不占用布局空间,相当于从布局中移除 占用空间,但完全透明
测量与布局 不参与测量和布局流程 参与测量和布局,只是不绘制
适用场景 临时隐藏且需释放空间 临时隐藏但保持布局结构

🔟3️⃣、getString() vs getText()

功能 :获取字符串资源
区别

维度 getString(int resId) getText(int resId)
返回类型 String CharSequence
支持资源类型 纯文本字符串 支持带样式的字符串(如 <b> 标签)
示例 getString(R.string.app_name) getText(R.string.styled_text)

总结

相似方法的核心区别通常体现在:

  • 线程安全性 (如 invalidate() 主线程 vs postInvalidate() 子线程)
  • 生命周期关联(如旧版启动 vs Activity Result API)
  • 性能与副作用 (如 commit() 同步 vs apply() 异步)
  • 适用场景 (如 dp 用于布局 vs sp 用于文字)

使用时需根据具体场景(线程、生命周期、性能需求等)选择,优先使用官方推荐的新 API(如 Activity Result API 替代 startActivityForResult())。

🔟4️⃣、其他

案例 1:finish() vs onBackPressed()(Activity 关闭相关)

相似点 :都可用于关闭当前 Activity
差异分析

  • finish():直接触发 Activity 销毁流程,调用后 Activity 进入 onDestroy() 生命周期,适合在代码逻辑中主动关闭页面(如点击 "完成" 按钮)。

    java 复制代码
    // 点击按钮关闭页面
    btnFinish.setOnClickListener(v -> finish());
  • onBackPressed():是系统回调方法,当用户按下物理返回键或导航栏返回按钮时触发。默认实现是调用 finish(),但可重写以添加额外逻辑(如双击返回退出、弹窗确认)。

    java 复制代码
    @Override
    public void onBackPressed() {
        // 自定义逻辑:如果是首页,双击返回退出
        if (isHomePage && System.currentTimeMillis() - lastBackTime < 2000) {
            super.onBackPressed(); // 调用父类实现(即 finish())
        } else {
            Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show();
            lastBackTime = System.currentTimeMillis();
        }
    }

选择依据 :主动关闭用 finish();拦截返回键行为用 onBackPressed()

案例 2:setVisibility(View.GONE) vs removeView()(View 移除相关)

相似点 :都可让 View 从界面消失
差异分析

  • setVisibility(View.GONE):View 仍存在于布局结构中,只是不显示且不占用空间,可通过 setVisibility(View.VISIBLE) 恢复显示,适合临时隐藏(如切换列表筛选状态)。

    java 复制代码
    // 筛选条件不满足时隐藏按钮
    btnFilter.setVisibility(filterCondition ? View.VISIBLE : View.GONE);
  • removeView():将 View 从父容器中彻底移除,若需再次显示需重新调用 addView() 添加,适合确定不再使用的场景(如动态表单删除某一行)。

    java 复制代码
    // 从父布局中移除不需要的输入项
    parentLayout.removeView(extraInputView);

选择依据 :临时隐藏且可能恢复用 GONE;永久移除用 removeView()

案例 3:notifyDataSetChanged() vs notifyItemChanged(int)(RecyclerView 刷新相关)

相似点 :都用于刷新 RecyclerView 列表
差异分析

  • notifyDataSetChanged():通知列表 "所有数据已变",会触发整个列表重新绑定和绘制,效率低,适合数据批量替换或结构变化(如切换数据源)。

    java 复制代码
    // 整体数据替换时使用
    mList = newData;
    adapter.notifyDataSetChanged();
  • notifyItemChanged(int position):仅通知指定位置的数据变化,只会重新绑定该位置的 Item,效率高,适合单个数据更新(如点赞状态变化)。

    java 复制代码
    // 仅更新第5项数据
    mList.get(5).setLiked(true);
    adapter.notifyItemChanged(5);

选择依据 :局部更新用 notifyItemXXX 系列方法;全量刷新才用 notifyDataSetChanged()

案例 4:postDelayed(Runnable, long) vs Handler.postDelayed(Runnable, long)(延迟任务相关)

相似点 :都可实现延迟执行任务
差异分析

  • View.postDelayed(Runnable, long):任务在 View 所在的线程(通常是主线程)执行,且会检查 View 是否已被销毁(mAttachInfo != null),避免内存泄漏,适合与 View 相关的延迟操作(如延迟隐藏提示框)。

    java 复制代码
    // 延迟3秒隐藏提示框
    tipView.postDelayed(() -> tipView.setVisibility(View.GONE), 3000);
  • Handler.postDelayed(Runnable, long):需要手动管理 Handler 的生命周期,若 Handler 持有 Activity 引用且未及时移除任务,可能导致内存泄漏,适合全局延迟任务(如定时轮询)。

    java 复制代码
    // 需在 Activity 销毁时调用 handler.removeCallbacksAndMessages(null)
    Handler handler = new Handler(Looper.getMainLooper());
    handler.postDelayed(() -> doPolling(), 5000);

选择依据 :与 View 相关的延迟任务用 View.postDelayed();全局任务用 Handler 并注意及时取消。

案例 5:getStringArray() vs getResources().obtainTypedArray()(数组资源获取相关)

相似点 :都用于获取资源文件中定义的数组
差异分析

  • getStringArray(int resId):直接获取字符串数组,适合简单的字符串数组(如 string-array 定义的列表项)。

    XML 复制代码
    <!-- res/values/arrays.xml -->
    <string-array name="city_list">
        <item>北京</item>
        <item>上海</item>
    </string-array>

    使用

    java 复制代码
    String[] cities = getResources().getStringArray(R.array.city_list);
  • obtainTypedArray(int resId):获取 typed-array 资源,支持多种类型(字符串、图片、尺寸等),适合复杂数组(如图文混排的列表)。

    XML 复制代码
    <!-- res/values/arrays.xml -->
    <typed-array name="icon_text_array">
        <item>@drawable/ic_home</item>
        <item>首页</item>
        <item>@drawable/ic_profile</item>
        <item>我的</item>
    </typed-array>

    运行

    java 复制代码
    TypedArray ta = getResources().obtainTypedArray(R.array.icon_text_array);
    Drawable homeIcon = ta.getDrawable(0);
    String homeText = ta.getString(1);
    ta.recycle(); // 必须回收,避免内存泄漏

选择依据 :纯字符串数组用 getStringArray();多类型数组用 typed-array 配合 obtainTypedArray()

相关推荐
超低空4 分钟前
Android MediaSession深度解析:车载音乐播放器完整案例
android·架构·客户端
00后程序员张5 分钟前
iOS 混淆实操指南多工具组合实现 IPA 混淆、加固与发布治理 IPA 加固
android·ios·小程序·https·uni-app·iphone·webview
xiaoshiquan12061 小时前
as强制过滤指定依赖版本库,解决该依赖不同版本冲突
android
2501_929157683 小时前
Switch 20.5.0系统最新PSP模拟器懒人包
android·游戏·ios·pdf
用户094 小时前
Kotlin Flow的6个必知高阶技巧
android·面试·kotlin
用户094 小时前
Flutter插件与包的本质差异
android·flutter·面试
用户094 小时前
Jetpack Compose静态与动态CompositionLocal深度解析
android·面试·kotlin
聆风吟º7 小时前
【Spring Boot 报错已解决】别让端口配置卡壳!Spring Boot “Binding to target failed” 报错解决思路
android·java·spring boot
非专业程序员Ping15 小时前
HarfBuzz概览
android·ios·swift·font
Jeled16 小时前
「高级 Android 架构师成长路线」的第 1 阶段 —— 强化体系与架构思维(Clean Architecture 实战)
android·kotlin·android studio·1024程序员节