Android(安卓)Kotlin 学习总结(一) 《KAE 优缺点并且深入字节码分析工作原理》
本章会分为以下内容:
1.Kotlin KAE介绍,使用和原始Android findViewById对比优缺点
2.Kotlin KAE所存在的问题
3.通过字节码分析他的实现原理
阅读本章内容大概需要您5分钟的时间
一、Kotlin KAE介绍,使用和原始Android findViewById对比优缺点
说起Koltin大家可能不陌生,Android的小伙伴,谷歌Android的一级语言,国内虽然还不算太流行,不过也慢慢火了起来,今天就来说一下Kotlin的一个扩展插件 kotlin-android-extensions , 简称KAE ,
官方文档 http://kotlinlang.org/docs/tutorials/android-plugin.html
1.1 KAE的使用
如果你的AndroidStudio版本比较低,那么你需要去在AndroidStudio里面下载Kotlin的支持,这里不讲述了(Google一下~)
我们就说一下版本比较高的AndroidStudio怎么使用KAE , 我们创建一个项目之后,我们需要在Project的Gradle里面添加上我们的 buildscript里添加上support_version字段 然后再我们的模块Gradle中plugin我们的AKE 具体见下图
这时候我们的KAE就算安装完毕了
关于使用:
在我们原来View绑定XML控件的时候,我们通常会做findViewById(R.id.xx)的工作,这是很头疼的事情,界面简单还好说,如果界面复杂,你会遇到下面这种事情
一大串的findViewById, 用插件生成还好说,手动写就很头疼,第一它样板代码,第二他太多了太多了太多了!,如果要写成全局的控件,上面还要写一份,就是双倍了有木有,但是我们使用KAE的话 就是如下的样子
有的小伙伴可能就会问了,findViewById呢,去哪了? 其实KAE帮我们做了这个事情,下面在字节码分析会讲到他是怎么做的,这里我们想使用控件,直接引入一个包就可以了,这个包并不是实际存在的,
这个包会直接绑定上我们的试图中所有的控件,怎么样,代码是不是简洁了很多。我们就可以节省更多的时间不去写findViewById了,把更多的时间用在控件的逻辑交互上,节省了开发时间。
二.Kotlin KAE所存在的问题
当我们的界面比较复杂,比如说我们想给ListView加一个Header的时候,我们可能要引入另一个View,当两个View控件id一样的时候,我们就会出现一个问题,如下图
也就是说,不同xml布局文件id相同的控件用在一个Acitivity中 会引起歧义,这时候我们可以通过别名(外号)的方式解决冲突在我们引包的地方加上个别名即可
但是解决问题的根源就是预防问题,所以当我们写id的时候还需要严谨一些!
三、通过字节码分析他的实现原理
我们就还是继续上面的代码来进行查看一下生成的字节码,生成的字节码我放在下面供大家参考
package github.nixo.com.github.Common.View;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;import github.nixo.com.github.Common.Present.LoginPersenter;import github.nixo.com.github.R.id;import github.nixo.com.github.mvp.Impl.BaseActivity;import java.util.HashMap;import kotlin.Metadata;import kotlin.jvm.internal.Intrinsics;import org.jetbrains.annotations.NotNull;import org.jetbrains.annotations.Nullable;@Metadata( mv = {1, 1, 11}, bv = {1, 0, 2}, k = 1, d1 = {"\u0000&\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u0003\n\u0002\b\u0005\u0018\u00002\b\u0012\u0004\u0012\u00020\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0003J\u0012\u0010\u0004\u001a\u00020\u00052\b\u0010\u0006\u001a\u0004\u0018\u00010\u0007H\u0016J\b\u0010\b\u001a\u00020\u0005H\u0016J\u000e\u0010\t\u001a\u00020\u00052\u0006\u0010\n\u001a\u00020\u000bJ\u0006\u0010\f\u001a\u00020\u0005J\u0006\u0010\r\u001a\u00020\u0005J\u0012\u0010\u000e\u001a\u00020\u00052\b\u0010\u000f\u001a\u0004\u0018\u00010\u0007H\u0016¨\u0006\u0010"}, d2 = {"Lgithub/nixo/com/github/Common/View/LoginActivity;", "Lgithub/nixo/com/github/mvp/Impl/BaseActivity;", "Lgithub/nixo/com/github/Common/Present/LoginPersenter;", "()V", "onCreate", "", "savedInstanceState", "Landroid/os/Bundle;", "onDestory", "onLoginError", "e", "", "onLoginStart", "onLoginSuccess", "onViewStateResotre", "saveInstanceState", "production sources for module app"})public final class LoginActivity extends BaseActivity { private HashMap _$_findViewCache; public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(2131361819); ((Button)this._$_findCachedViewById(id.login_login)).setOnClickListener((OnClickListener)(new OnClickListener() { public final void onClick(View it) { LoginPersenter var10000 = (LoginPersenter)LoginActivity.this.getPresenter(); EditText var10001 = (EditText)LoginActivity.this._$_findCachedViewById(id.login_account); Intrinsics.checkExpressionValueIsNotNull(var10001, "login_account"); String var2 = var10001.getText().toString(); EditText var10002 = (EditText)LoginActivity.this._$_findCachedViewById(id.login_password); Intrinsics.checkExpressionValueIsNotNull(var10002, "login_password"); var10000.doLogin(var2, var10002.getText().toString()); } })); } public final void onLoginSuccess() { CharSequence message$iv = (CharSequence)"登陆成功"; Toast var3 = Toast.makeText(this, message$iv, 0); var3.show(); Intrinsics.checkExpressionValueIsNotNull(var3, "Toast\n .makeText(… show()\n }"); } public final void onLoginError(@NotNull Throwable e) { Intrinsics.checkParameterIsNotNull(e, "e"); CharSequence message$iv = (CharSequence)"登陆失败"; Toast var4 = Toast.makeText(this, message$iv, 0); var4.show(); Intrinsics.checkExpressionValueIsNotNull(var4, "Toast\n .makeText(… show()\n }"); } public final void onLoginStart() { } public void onViewStateResotre(@Nullable Bundle saveInstanceState) { } public void onDestory() { } 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(); } }}
我们首先找到我们的login_login控件,我们可以发现他也执行了findViewById,只不过是findCacheViewById,其实这里使用了HashMap作为控件缓存,我们看一下这两个方法,就是判断是否有这个缓存,如果用直接用,没有在调用findViewById,所以Kotlin的KAE 其实就是在编译时期将我们的控件执行了findViewById的操作,它只不过帮我们做了这件事,并且是编译时期调用,变为相同代码,原理跟ButterKinfe差不多,但是比ButterKinfe更简洁,而且使用KAE有一个好处,我们保证了类型的安全性,不会因为写错控件类型而导致强转错误~
以上就是本章的全部内容了,今天中秋节,祝大家中秋节快乐!
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- Android(安卓)转:应用程序窗体显示状态操作(requestWindowFeature(
- Kotlin基础(一)android studio中配置Kotlin
- Android之MVC模式的使用
- 移动端跨平台开发方案比较
- android客户端和php服务简单交互
- 【Android】界面布局之 LinearLayout(线性布局)
- Android(安卓)html5和Android之间的交互
- Android中ImageView的scaleType 属性说明。