Kotlin 为什么不用findViewById

前些天面试的时候遇到过一个这样的问题,当时不知道是为什么,因为自己也没有真正用kotlin做过项目,只是写过一些小demo, 然后回来就自己查查,
发现网上对kotlin 内部实现的文章很少,好不容易找到一篇,很不错的资料,自己写下来记录下,也用来分享给其他人。

AndroidStudio中可以直接打开kotlin Bytecode,进行反编译查看编译后的代码。 Tools->Kotlin->Show Kotlin Bytecode->Decompile

查看编译后的代码,我们可以发现很有趣的东西。


...
   private HashMap _$_findViewCache;

   protected void onCreate(@Nullable Bundle savedInstanceState) {
      ...
      ((TextView)this._$_findCachedViewById(id.helloTv)).setText((CharSequence)"Hello Kotlin!");
   }

   public View _$_findCachedViewById(int var1) {
      if(this._$_findViewCache == null) {
         this._$_findViewCache = new HashMap();
      }

      View var2 = (View)this._$_findViewCache.get(Integer.valueOf(var1));
      if(var2 == null) {
         var2 = this.findViewById(var1);
         this._$_findViewCache.put(Integer.valueOf(var1), var2);
      }

      return var2;
   }

   public void _$_clearFindViewByIdCache() {
      if(this._$_findViewCache != null) {
         this._$_findViewCache.clear();
      }

   }
...

代码很简单,在第一次使用控件的时候,在缓存集合中进行查找,有就直接使用,没有就通过findViewById进行查找,并添加到缓存集合中。其还提供了_$_clearFindViewByIdCache()方法用于清除缓存,在我们想要彻底替换界面控件时可以使用到。

我们再来看看Fragment中使用,编译过后的代码是如何的。

 private HashMap _$_findViewCache;

   ...

   public void onViewCreated(@Nullable View view, @Nullable Bundle savedInstanceState) {
      super.onViewCreated(view, savedInstanceState);
      ((TextView)this._$_findCachedViewById(id.helloTv)).setText((CharSequence)"Hello Fragment By Kotlin!");
   }

   public View _$_findCachedViewById(int var1) {
      if(this._$_findViewCache == null) {
         this._$_findViewCache = new HashMap();
      }

      View var2 = (View)this._$_findViewCache.get(Integer.valueOf(var1));
      if(var2 == null) {
         View var10000 = this.getView();
         if(var10000 == null) {
            return null;
         }

         var2 = var10000.findViewById(var1);
         this._$_findViewCache.put(Integer.valueOf(var1), var2);
      }

      return var2;
   }

   public void _$_clearFindViewByIdCache() {
      if(this._$_findViewCache != null) {
         this._$_findViewCache.clear();
      }

   }

   // $FF: synthetic method
   public void onDestroyView() {
      super.onDestroyView();
      this._$_clearFindViewByIdCache();
   }

和Activity的唯一区别就是在onDestroyView()方法中调用了_$_clearFindViewByIdCache(),来清楚缓存,所以我们不用担心在View销毁的时候,缓存不能及时释放的问题。

到这里,我想大家肯定很清楚了,我们并没有完全的离开findViewById,只是kotlin的扩展插件利用缓存的方式让我们开发更方便、更快捷。

参考链接:http://blog.csdn.net/andrlin/article/details/78055825

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值