Kotlin中的kotlin-android-extensions插件如何实现findViewById()
·
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对该实例进行缓存,下次查询就没必要重复查询了。
更多推荐



所有评论(0)