本章会分为以下内容:

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有一个好处,我们保证了类型的安全性,不会因为写错控件类型而导致强转错误~

 

以上就是本章的全部内容了,今天中秋节,祝大家中秋节快乐!

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. Android(安卓)转:应用程序窗体显示状态操作(requestWindowFeature(
  3. Kotlin基础(一)android studio中配置Kotlin
  4. Android之MVC模式的使用
  5. 移动端跨平台开发方案比较
  6. android客户端和php服务简单交互
  7. 【Android】界面布局之 LinearLayout(线性布局)
  8. Android(安卓)html5和Android之间的交互
  9. Android中ImageView的scaleType 属性说明。

随机推荐

  1. Android缓存机制——一般存储实现
  2. ListView.setOnItemClickListener无效
  3. Android(安卓)stuido 中使用androidx.fra
  4. 【Android获取图片资源的4种方式】
  5. 如何解决Android(安卓)Emulator显示窗口
  6. Android(安卓)StudioGradle 一键快速打包
  7. Android中BindService方式使用的理解
  8. 2017-3-28(React-Native与Android原生代
  9. Android菜鸟日记19-图片旋转
  10. 自定义ProgressBar样式