kotlin-android-extensions插件简化了Activity中的代码编写。不用通过findViewById()获取控件的实例了。

这个功能的实现可以通过反编译分析。

现在将以下代码转换为Kotlin字节码,然后通过反编译的方式将他还原为java代码,来观察kotlin-android-extensions插件背后实现原理。

 

 

 这就是kotlin代码对应的字节码。

然后点击以下Decompile将kotlin字节码反编译为java代码:

package com.yinlei.kotlinfindviewbyid;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.yinlei.kotlinfindviewbyid.R.id;
import java.util.HashMap;
import kotlin.Metadata;
import org.jetbrains.annotations.Nullable;

@Metadata(
   mv = {1, 1, 16},
   bv = {1, 0, 3},
   k = 1,
   d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u0012\u0010\u0003\u001a\u00020\u00042\b\u0010\u0005\u001a\u0004\u0018\u00010\u0006H\u0014¨\u0006\u0007"},
   d2 = {"Lcom/yinlei/kotlinfindviewbyid/MainActivity;", "Landroidx/appcompat/app/AppCompatActivity;", "()V", "onCreate", "", "savedInstanceState", "Landroid/os/Bundle;", "app"}
)
public final class MainActivity extends AppCompatActivity {
   private HashMap _$_findViewCache;

   protected void onCreate(@Nullable Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      this.setContentView(1300009);
      ((Button)this._$_findCachedViewById(id.button)).setOnClickListener((OnClickListener)(new OnClickListener() {
         public final void onClick(View it) {
            Toast.makeText((Context)MainActivity.this, (CharSequence)"You clicked button", 0).show();
         }
      }));
   }

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

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

      return var2;
   }

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

   }
}

通过代码可以看到插件会在activity中自动生成一个

_$_findCachedViewById()的方法,取这个名字是为了防止和我们编码定义的方法重名,这个方法中根据传入的id值调用findviewbyid()来查询并获取控件的实例,然后使用了hashMap对该实例进行缓存,下次查询就没必要重复查询了。

更多推荐