记录下使用ViewBinding 反射遇到了混淆的坑

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

前几天项目中对接了相芯美颜sdk, 需要自定义美颜,滤镜和sticke。开发完后提交给测试同学,debug环境没问题,release环境点击就崩溃,作为一名老司机,首先想到就是混淆的问题,去Firebase上看crash日志。

通过日志看,是ViewBinding.getRoot()空指针了,首先想到的是这次代码作为美颜工具类放在了utils包下,我可以把整个Faceunity的文件夹添加到混淆中,同时把相芯美颜sdk添加到混淆中,于是添加了一下混淆。

-keep class com.faceunity.** { *; }
-keep class com.xxxx.android.ui.utils.faceunity.** { *; }

想着这样总可以了吧,但是当满怀期待运行起来后,点击还是会crash,crash log还是上面那个,这个时候感觉很懵逼,于是就去检查代码,崩溃的地方是我自定义了一个BindingViewHolder继承自RecyclerView的ViewHold,代码如下:

public class BindingViewHolder<T extends ViewBinding> extends RecyclerView.ViewHolder {
    public final T binding;

    public BindingViewHolder(@NonNull T binding) {
        super(binding.getRoot());
        this.binding = binding;
    }

    public T inflate(@NonNull LayoutInflater inflater) {
        try {
            Class<T> c = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
            if (c != null)
                return (T) c.getDeclaredMethod("inflate", LayoutInflater.class).invoke(null, inflater);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

看到代码中使用了反射,这个时候就感觉应该是反射的问题,使用反射的意图本来是想走捷径,但是这个捷径反而更远了。既然定位到是ViewBinding反射的问题,那就给ViewBinding加混淆,最后chatgpt给了一个不错的混淆:

-keepclassmembers class * implements androidx.viewbinding.ViewBinding { *; }

您可能感兴趣的与本文相关的镜像

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

既然你**只想使用 ViewBinding**,而不是 DataBinding,那么你的 XML 布局文件**不需要**使用 `<layout>` 标签包裹,否则会触发 DataBinding 编译器并报错: > **must include a layout** --- ### ✅ 正确使用 ViewBinding 的方式 #### ✅ 1. 启用 ViewBinding(在 `build.gradle` 中) ```groovy android { ... buildFeatures { viewBinding = true } } ``` #### ✅ 2. 布局文件不需要 `<layout>` 标签 你的 `activity_main.xml` 文件结构是正确的,只需要确保**没有使用 `<layout>` 标签**。 ```xml <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/ll_bottom_sheet" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" app:layout_behavior="@string/bottom_sheet_behavior"> <!-- 子视图 --> </LinearLayout> <Button android:id="@+id/btn_bottom_sheet" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Toggle Sheet" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> ``` --- ### ✅ 3. 在 Activity 中使用 ViewBinding ```kotlin class MainActivity : AppCompatActivity() { private var _binding: ActivityMainBinding? = null private val binding get() = _binding!! private lateinit var bottomSheetBehavior: BottomSheetBehavior<LinearLayout> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) _binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) bottomSheetBehavior = BottomSheetBehavior.from(binding.llBottomSheet) binding.btnBottomSheet.setOnClickListener { if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) { bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED } else { bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED } } } override fun onDestroy() { super.onDestroy() _binding = null } } ``` --- ### ✅ 注意事项 | 项目 | 说明 | |------|------| | ViewBinding | 不需要 `<layout>` 标签 | | DataBinding | 必须用 `<layout>` 包裹布局 | | 混淆使用 | 如果 XML 中写了 `<layout>`,即使你没用 DataBinding,也会触发 DataBinding 编译器 | | 类名生成 | `activity_main.xml` → `ActivityMainBinding` | --- ### ✅ 常见错误修复 | 错误 | 原因 | 解决方法 | |------|------|----------| | `must include a layout` | XML 被识别为 DataBinding 布局 | 移除 `<layout>` 标签 | | `ActivityMainBinding` 不存在 | ViewBinding 未启用或未同步项目 | 启用 ViewBinding 并 Rebuild 项目 | | Binding 类无法导入 | 包名不一致或文件名错误 | 检查 XML 文件名与 Binding 类名是否匹配 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张海龙(Jason Zhang)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值