您的位置:首页 > 移动开发 > Android开发

Android KTX与Kotlin Android Extensions

2018-03-23 20:17 357 查看

Android KTX

Android KTX是Google官方推荐的一套便利的Android API扩展函数库。因还处于beta阶段,相关API并不丰富,但既然是出自JakeWharton大神之手,必然是前途无限的。其目前提供了如下的API



Kotlin 扩展特性

Android KTX能扩充Android API得益于Kotlin扩展函数的特性,即能在不改变现有类的前提下,扩展这个类的功能,如增加属性或方法。

从语法上来看,Kotlin扩展函数与普通方法的区别是函数名前多了接收者类型的前缀

如下Android KTX中对String的扩展:

inline fun String.htmlEncode(): String = TextUtils.htmlEncode(this)


实现原理:Kotlin扩展函数实质上就是一个静态方法,本文就从代码上去寻找答案:

首先,上述String.htmlEncode这个扩展函数其等效的java如下,特点是有一个扩展函数前缀类型的参数

public final class StringKt {
@NotNull
public static final String htmlEncode(@NotNull String $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
String var10000 = TextUtils.htmlEncode($receiver);
Intrinsics.checkExpressionValueIsNotNull(var10000, "TextUtils.htmlEncode(this)");
return var10000;
}
}


其次,测试htmlEncode方法:

fun testHtmlEncode() {
val str = """<> & " '""".htmlEncode()
print(str)
}


接着,testHtmlEncode对应的java代码如下,出乎意料的是这段代码并不是调用StringKt.htmlEncode,而是以内联的方式潜入代码。

public final void testHtmlEncode() {
String $receiver$iv = "<> & \" '";
String var10000 = TextUtils.htmlEncode($receiver$iv);
Intrinsics.checkExpressionValueIsNotNull(var10000, "TextUtils.htmlEncode(this)");
String str = var10000;
System.out.print(str);
}


最后,排除原因是这个扩展函数声明为inline,去除这个关键字就是普通的静态方法调用。如下:

public final void testhtmlEncode() {
String str = StringKt .htmlEncode("<> & \" '");
System.out.print(str);
}


Kotlin Android Extensions

Kotlin Android Extensions是Kotlin官方推出的简化Android开发的Gradl
a292
e插件,目前主要针对如下几种场景:

View Binding:即UI绑定,不需要再依赖其它library(如butterknife),即可实现UI绑定

View Caching:UI缓存,内置已实现了UI的缓存策略

Parcelable:使用注解即可实现Android的Parcelable序列化

工作原理:Kotlin Android Extensions这个插件使用了自动代码生成的方式,自动帮使用者实现UI绑定以及缓存机制

layout如下:

<TextView
android:id="@+id/completionRateView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="11.5%"
android:textColor="@color/text_blue"/>


设置文本:

fun test() {
completionRateView.text = "100%"
}


反编译后代码如下,可以发现其实是调用了本类中的_findCachedViewById方法

fun test() {
TextView var10000 = (TextView)this._$_findCachedViewById(id.completionRateView);
Intrinsics.checkExpressionValueIsNotNull(var10000, "completionRateView");
var10000.setText((CharSequence)"100%");
}


_findCachedViewById方法如下,使用了HashMap进行缓存View,流程是:先取缓存,无缓存则调用findViewById

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;
}


另外,其缓存策略还包括如下的清除方法:

小结:Kotlin Android Extensions并非直接为UI组件(Activity或Fragment)生成上述可以直接调用的属性,而只是在代码编译直接自动实现了UI的绑定。

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

}


KTX

经过上述两小节内容,基本弄清楚了Kotlin扩展函数和Kotlin Android Extensions的原理,再来看Android KTX,它实际上就是一套与Android API相关的扩展函数的集合。

借助于Kotlin扩展函数的特性,Android KTX能实现一套不需修改现有的Android API的代码即可为其实现扩展。

Android KTX好处就是简化Android代码的编写。

至此Android KTX与Kotlin Android Extensions区别已很明显,但它们的目的是一致的:more concise, pleasant, and idiomatic
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: