使用Kotlin高效地开发Android App(一)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 使用Kotlin高效地开发Android App(一)

背景



最近我们在做区块链相关的钱包项目,新的App使用全新的技术栈。在Android中我们使用Kotlin+RxJava+Android Architecture Components,在iOS中使用Swift+RxSwift。本文不讨论App的架构,只讨论项目中所使用到的Kotlin的特性。


在Android的App中,可以毫不夸张地说,我们95%以上的代码使用了Kotlin开发的。由此,很有必要对这一阶段使用Kotlin做一个简单的小结。


使用的Kotlin特性:



一.扩展函数


Kotlin允许开发者在不改变已有类的情况下,为某个类添加新的函数。这个特性叫做扩展函数。


举一个简单的例子。如果要关闭一个I/O流,使用Java可能是写一个工具方法。

/**
     * 安全关闭io流
     * @param closeable
     */
    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


对Kotlin而言,可以对Closeable扩展一个函数closeQuietly()。

fun Closeable?.closeQuietly() {
    try {
        this?.close()
    } catch (e: Throwable) {
    }
}


之后,任何实现了Closeable接口的类,都可以使用它本身的closeQuietly()方法来关闭流。我们不再需要那个工具方法了。


在项目中,我们使用扩展函数对Glide做了封装,大大简化了Glide的使用。

/**
 * 占位符矩形
 */
fun ImageView.load(url: String) {
    get(url).placeholder(R.drawable.shape_default_rec_bg)
            .error(R.drawable.shape_default_rec_bg)
            .into(this)
}
/**
 * 占位符圆角矩形
 */
fun ImageView.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)
}
/**
 * 占位符圆形
 */
fun ImageView.loadCircle(url: Drawable) {
    get(url).placeholder(R.drawable.shape_default_circle_bg)
            .error(R.drawable.shape_default_circle_bg)
            .into(this)
}
fun ImageView.loadCircle(url: String) {
    get(url).placeholder(R.drawable.shape_default_circle_bg)
            .error(R.drawable.shape_default_circle_bg)
            .into(this)
}
fun ImageView.get(url: String): GlideRequest<Drawable> = GlideApp.with(context).load(url)
fun ImageView.get(url: Drawable): GlideRequest<Drawable> = GlideApp.with(context).load(url)


除此之外,我们还很多地方都用到了扩展函数。


我顺便更新了我的Kolin的工具类库,它包括各种utils和各种extension

https://github.com/fengzhizi715/SAF-Kotlin-Utils


二.尾随闭包



一开始我并不了解这个概念。偶然间我看到我们的小伙伴在使用RxBus时,写下了这样的代码:

RxBus.get().register(LogoutEvent::class.java) { refresh() }


当时我感觉很疑惑,因为RxBus是我写的,记得没有提供这样的方法啊。点击register()方法进去看之后,发现register是这样的:

public <T> Disposable register(Class<T> eventType, Consumer<T> onNext) {
        return toObservable(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext);
    }


由于使用了Kotlin,该register方法的使用可以简化成这样:

RxBus.get().register(LogoutEvent::class.java,{
            refresh()
        })


由于register()最后一个参数是一个方法或者说是一个闭包,可以把方法或者闭包提到最外面。变成项目中看到的样子:

RxBus.get().register(LogoutEvent::class.java) { refresh() }


这就是尾随闭包,可以让代码看起来更加简洁。


三.with的用法



with是将某个对象作为函数的参数,在函数块内可以通过 this 指代该对象。在函数块内可以直接调用对象的方法或者属性。

/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}


在使用with之前的某个Adapter

class AppPublisherAdapter : BaseAdapter<BoundAppInfoResponse.AppInfo>() {
    override fun getLayoutId(viewType: Int): Int = R.layout.cell_app_publisher
    override fun onBindViewHolderImpl(holder: BaseViewHolder, position: Int,content: BoundAppInfoResponse.AppInfo) {
        holder.itemView.tv_game_name.text = content.name
        if (content.is_bound) {
            holder.itemView.tv_bound_user_name.text = content.bound_user_name
            holder.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(content.logo_url)
    }
}


使用with之后,该函数块可以省略"content."

class AppPublisherAdapter : BaseAdapter<BoundAppInfoResponse.AppInfo>() {
    override fun getLayoutId(viewType: Int): Int = R.layout.cell_app_publisher
    override fun onBindViewHolderImpl(holder: BaseViewHolder, position: Int, content: BoundAppInfoResponse.AppInfo) {
        with(content) {
            holder.itemView.tv_game_name.text = name
            if (is_bound) {
                holder.itemView.tv_bound_user_name.text = bound_user_name
                holder.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-log


Retrofit日志拦截器的github地址:

https://github.com/fengzhizi715/saf-logginginterceptor


日志拦截器的效果图:

image.png

request的效果图.jpeg


image.png

response的效果图.jpeg


总结



Kotlin吸收了多种语言的优点,相对于Java有很多激动人心的特性,极大地提高了开发效率。本文介绍的特性也只是沧海一粟。接下来,我会整理更多项目中所使用的Kotlin特性。


BTW,我在写这篇文章的时候国内第一个钱包版本刚刚做完,开始第一轮测试。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
打赏
0
0
0
0
0
分享
相关文章
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
150 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
34 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
MNN-LLM App 是阿里巴巴基于 MNN-LLM 框架开发的 Android 应用,支持多模态交互、多种主流模型选择、离线运行及性能优化。
1061 14
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
escrcpy 是一款基于 Scrcpy 的开源项目,使用 Electron 构建,提供图形化界面来显示和控制 Android 设备。它支持 USB 和 Wi-Fi 连接,帧率可达 30-120fps,延迟低至 35-70ms,启动迅速且画质清晰。escrcpy 拥有丰富的功能,包括自动化任务、多设备管理、反向网络共享、批量操作等,无需注册账号或广告干扰。适用于游戏直播、办公协作和教育演示等多种场景,是一款轻量级、高性能的 Android 控制工具。
小游戏源码开发之可跨app软件对接是如何设计和开发的
小游戏开发团队常需应对跨平台需求,为此设计了成熟的解决方案。流程涵盖游戏设计、技术选型、接口设计等。首先明确游戏功能与特性,选择合适的技术架构和引擎(如Unity或Cocos2d-x)。接着设计通用接口,确保与不同App的无缝对接,并制定接口规范。开发过程中实现游戏逻辑和界面,完成登录、分享及数据对接功能。最后进行测试优化,确保兼容性和性能,发布后持续维护更新。
语音app系统软件源码开发搭建新手启蒙篇
在移动互联网时代,语音App已成为生活和工作的重要工具。本文为新手开发者提供语音App系统软件源码开发的启蒙指南,涵盖需求分析、技术选型、界面设计、编码实现、测试部署等关键环节。通过明确需求、选择合适的技术框架、优化用户体验、严格测试及持续维护更新,帮助开发者掌握开发流程,快速搭建功能完善的语音App。
构建高效Android应用:Kotlin的协程与Flow
【4月更文挑战第26天】随着移动应用开发的不断进步,开发者寻求更简洁高效的编码方式以应对复杂多变的业务需求。在众多技术方案中,Kotlin语言凭借其简洁性和强大的功能库逐渐成为Android开发的主流选择。特别是Kotlin的协程和Flow这两个特性,它们为处理异步任务和数据流提供了强大而灵活的工具。本文将深入探讨如何通过Kotlin协程和Flow来优化Android应用性能,实现更加流畅的用户体验,并展示在实际开发中的应用实例。
构建高效Android应用:Kotlin与协程的完美融合
【2月更文挑战第25天】 在移动开发领域,性能优化和应用响应性的提升是永恒的追求。随着Android Jetpack组件库的不断丰富,Kotlin语言已经成为Android开发的首选。而Kotlin协程作为一种新的并发处理方案,它以轻量级线程的形式,为开发者提供了简洁高效的异步编程手段。本文将深入探讨Kotlin协程在Android应用中的实践运用,以及如何通过这种技术改善用户界面的流畅度和后台任务的处理能力,进而构建出更高效、更稳定的Android应用。
构建高效Android应用:Kotlin与协程的完美结合
【2月更文挑战第30天】在移动开发领域,性能优化和流畅的用户体验是关键。本文深入探讨了如何通过结合Kotlin语言和协程技术来提升Android应用的性能和响应能力。我们将分析Kotlin的优势,介绍协程的基本概念,并通过实际案例展示如何在应用中实现协程以简化异步编程,从而提供更加高效的解决方案。
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
71 1

热门文章

最新文章

  • 1
    Android历史版本与APK文件结构
    28
  • 2
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    5
  • 3
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    62
  • 4
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    17
  • 5
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    34
  • 6
    如何利用Java和Kotlin实现动态网页内容抓取
    3
  • 7
    MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
    310
  • 8
    即时通讯安全篇(一):正确地理解和使用Android端加密算法
    15
  • 9
    原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力
    38
  • 10
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    13