StarWarsMinions.jpg背景最近在做一个区块链相关的钱包项目,新的app使用了全新的技术栈。我们在Android中使用Kotlin+RxJava+AndroidArchitectureComponents,在iOS中使用Swift+RxSwift。本文不讨论App的架构,只讨论项目中使用的Kotlin的特点。在AndroidApp中,毫不夸张地说,我们95%以上的代码都是使用Kotlin开发的。因此,有必要对现阶段使用Kotlin做一个简单的总结。使用的Kotlin特性:1.扩展函数Kotlin允许开发者在不改变现有类的情况下向类中添加新的函数。此功能称为扩展功能。举一个简单的例子。如果要关闭I/O流,可以使用Java编写实用方法。/***安全地关闭io流*@paramcloseable*/对于Kotlin,一个函数closeQuietly()可以扩展为Closeable。在funCloseable?.closeQuietly(){try{this?.close()}catch(e:Throwable){}}之后,任何实现Closeable接口的类都可以使用自己的closeQuietly()方法关闭流。我们不再需要那个实用方法了。在项目中,我们使用扩展函数对Glide进行封装,大大简化了Glide的使用。/***占位符矩阵*/funImageView.load(url:String){get(url).placeholder(R.drawable.shape_default_rec_bg).error(R.drawable.shape_default_rec_bg).into(this)}/***占位符圆角形状*/funImageView.loadRound(url:String){get(url).placeholder(R.drawable.shape_default_round_bg).error(R.drawable.shape_default_round_bg)//.apply(RequestOptions.bitmapTransform(RoundedCornersTransformation)(DisplayUtil.dp2px(context,6f),0)).transform(RoundedCornersTransformation(DisplayUtil.dp2px(context,6f),0)).into(this)}/***占位符号圆*/funImageView.loadCircle(url:Drawable){get(url).placeholder(R.drawable.shape_default_circle_bg).error(R.drawable.shape_default_circle_bg).into(this)}funImageView.loadCircle(url:String){get(url).placeholder(R.drawable.shape_default_circle_bg).error(R.drawable.shape_default_circle_bg).into(this)}funImageView.get(url:String):GlideRequest=GlideApp.with(context).load(url)funImageView.get(url:Drawable):GlideRequest=GlideApp.with(context).load(url)除此之外,我们还有很多地方都用到了扩展函数。顺便更新一下我的Kolin工具库,里面有各种utils和各种扩展https://github.com/fengzhizi715/SAF-Kotlin-Utils2.一开始不明白尾随闭包的概念。偶尔看到小伙伴在使用RxBus时写下这样的代码:RxBus。我写了,但是我记得没有提供这样的方法。点击register()方法查看后发现register是这样的:publicDisposableregister(ClasseventType,ConsumeronNext){returntoObservable(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext);}由于Kotlin是used,register方法的使用可以简化如下:方法可以是或者闭包提到最外层。变成你在项目中看到的样子:RxBus.get().register(LogoutEvent::class.java){refresh()}这个就是尾随闭包,可以让代码看起来更简洁。3.with的用法with是将一个对象作为函数的参数,在函数块中可以引用这个对象。在功能块中,可以直接调用对象的方法或属性。/***用给定的[接收器]作为接收器调用指定的函数[块]并返回结果。*/@kotlin.internal.InlineOnlypublicinlinefunwith(接收器:T,块:T.()->R):R{contract{callsInPlace(block,InvocationKind.EXACTLY_ONCE)}returnreceiver.block()}在使用之前的某个AdapterclassAppPublisherAdapter:BaseAdapter(){overridefungetLayoutId(viewType:Int):Int=R.layout.cell_app_publisheroverridefunonBindViewHolderImpl(holder:BaseViewHolder,position:Int,content:BoundAppInfoResponse.AppInfo){holder.itemView.tv_game_name.text=content.nameif(content.is_bound){holder.itemView.tv_bound_user_name.text=content.bound_user_nameholder.itemView.tv_bound_user_name.setTextColor(context.resources.getColor(R.color.color_bound_user_name))}else{holder.itemView.tv_bound_user_name.text=context.getString(R.string.bind_on_account)holder.itemView.tv_bound_user_name.setTextColor(context.resources.getColor(R.color.color_bind_on_account))}holder.itemView.iv_game_icon.load(内容。标识_url)}}使用with后,功能块可以省略“content”。AppInfo){with(内容){holder.itemView.tv_game_name.text=nameif(is_bound){holder.itemView.tv_bound_user_name.text=bound_user_nameholder.itemView.tv_bound_user_name.setTextColor(context.color(R.color.color_bound_user_name))}else{holder.itemView.tv_bound_user_name.text=context.string(R.string.bind_on_account)holder.itemView.tv_bound_user_name.setTextColor(context.color(R.color.color_bind_on_account))}holder.itemView.iv_game_icon.load(logo_url)}}}四。这部分的其他内容不是Kotlin的特性,而是我用Kotlin开发的一个工具,比如日志框架L和Retrofit的日志拦截器。这些库其实是很久以前开发的,最近功能稍微升级了。L的github地址:https://github.com/fengzhizi715/SAF-Kotlin-logRetrofit日志拦截器的github地址:https://github.com/fengzhizi715/saf-logginginterceptor日志拦截器效果图:请求效果图。jpegresponse.jpeg效果图总结Kotlin吸收了多种语言的优点,相比Java有很多令人兴奋的特性,大大提高了开发效率。本文中介绍的功能只是沧海一粟。接下来我会整理更多项目中用到的Kotlin特性。BTW,在我写这篇文章的时候,国内第一个钱包版本刚刚完成,第一轮测试开始了。
