分享一次失败的经历 面试,第一行代码读书笔记 Kotlin Android,2024Android高级进阶学习资料
launch {
println(“launch1 ${Thread.currentThread().name}”)
delay(1000)
println(“launch1 finished”)
}
launch {
println(“launch2 ${Thread.currentThread().name}”)
delay(1000)
println(“launch2 finished”)
}
}
}
这里的launch函数和刚才的GlobalScope.launch不一样,这个launch只能在协程的作用域下面调用,且会创建一个子协程.子协程的特点是如果外层作用域的协程结束了,那么该作用域下的所有子协程也会一同结束.
上面的输出如下:
launch1 main
launch2 main
launch1 finished
launch2 finished
日志是交叉打印的,很明显,这是并发执行的.但是线程却是相同的线程.这里由编程语言来决定如何在多个协程之间进行调度,让谁挂起,让谁运行.调度过程不需要操作系统参与,这使得协程并发效率出奇得高.
9.3 suspend 挂起
当需要将部分代码提取到一个单独的函数中,这个函数是没有协程作用域的.Kotlin提供一个suspend关键字,使用它可以将任意函数声明成挂起函数,挂起函数之间是可以互相调用的.
suspend只能声明挂起函数,而不能提供协程作用域,在里面调用launch(必须在协程作用域调用才行)是不得行的.要想有协程作用域,可以使用coroutineScope.
coroutineScope也是一个挂起函数,因此可以在其他任何挂起函数中调用.coroutineScope会继承外部的协程作用域并创建一个子作用域. 于是可以这样用:
suspend fun printDot() {
coroutineScope {
launch {
println(“.”)
delay(1000)
println(“延迟之后的输出”)
}
}
}
coroutineScope有点类似runBlocking,保证其作用域内的所有代码和子线程全部执行完之前,会一直阻塞当前协程.
但是runBlocking会阻塞当前线程,影响较大.而coroutineScope只会阻塞当前协程,不会影响其他协程,也不会影响其他线程.
可创建新的协程作用域:
-
GlobalScope.launch 可在任何地方调用
-
runBlocking 可在任何地方调用
-
lanuch
-
coruotineScope
9.4 更多的作用域构建器
runBlocking会阻塞线程,只能在测试环境下使用.而GlobalScope.launch是顶层协程,比如在Activity中使用来请求网络,还没请求回来的时候,Activity已关闭,这时需要手动管理(去取消)这个顶层协程,比较麻烦. 调用下面的代码会取消顶层协程.
val job = GlobalScope.launch { }
job.cancel()
但是实际项目中,一般会用CoroutineScope
val job = Job()
//返回的是CoroutineScope对象 这里是调用的CoroutineScope方法
val scope = CoroutineScope(job)
scope.launch {
}
所有使用CoroutineScope对象的launch创建的协程统统会被job所管理(都是在它的作用域下面).大大降低协程维护成本.
9.5 创建协程,并获取其执行结果
使用async函数,就可以获取协程的执行结果.它会创建一个子协程,并返回Deferred对象,然后我们调用其await方法即可知道结果.下面是简单计算一下5+5
runBlocking {
val result = async {
delay(100)
5 + 5
}.await()
println(result)
}
注意,调用await方法之后会阻塞当前协程,直到子协程拿到结果,才会执行后面的代码(对应上面是println语句).为了提高效率,可以先拿到返回Deferred对象,最后需要结果的时候才调用await方法
runBlocking {
val start = System.currentTimeMillis()
val deferred1 = async {
delay(1000)
5 + 5
}
val deferred2 = async {
delay(1000)
6 + 6
}
println(“结果是 ${deferred1.await() + deferred2.await()}”)
val end = System.currentTimeMillis()
println(“花费时间: ${end - start}”)
}
9.6 withContext
withContext大致是async函数的简化版,它是一个挂起函数,返回结果是withContext函数体内最后一行代码.相当于val result = async{5+5}.await()
runBlocking {
val result = withContext(Dispatchers.Default) {
5 + 5
}
println(result)
}
调用withContext函数后,函数体内的代码会被立即执行,同时需要指定一个线程参数.这个参数有如下几个值:
-
Dispatchers.Default 会开启子线程,并使用一种较低并发的线程策略.适合计算密集型任务.
-
Dispatchers.IO 会开启子线程,并使用一种较高并发的线程策略.网络请求比较合适
-
Dispatchers.Main 不会开启子线程,而是在Android主线程执行代码.
9.7 使用协程简化回调
suspendCoroutine 函数可以将当前协程立即挂起,然后在一个普通的线程执行lambda表达式中的代码.Lambda表达式的参数是一个Continuation参数,调用它的resume方法或resumeWithException可以让协程恢复执行.
来看一段代码:
suspend fun request(address: String): String {
return suspendCoroutine { continuation ->
HttpUtil.sendHttpRequest(address, object : HttpCallbackListener {
override fun onFinish(response: String) {
continuation.resume(response)
}
override fun onError(e: Exception) {
continuation.resumeWithException(e)
}
})
}
}
GlobalScope.launch {
val response = request(“https://www.baidu.com/”)
Log.d(“xfhy”, “网络请求结果 : $response”)
}
将网络请求的代码用suspendCoroutine包装一下,免得每次去手动生成一个匿名类,然后在里面拿到结果的时候调用continuation的resume方法将结果返回,这样在外面即可拿到结果. 使用request方法请求网络,只需要写一句代码即可.上面为了实例,没有加try…catch.

Linux内核
Android平台的基础是Linux内核.
硬件抽象层(HAL)
硬件抽象层提供标准界面,向更高级别的Java API框架显示设备硬件功能.
Android Runtime
对于运行Android 5.0(API 21) 或更高版本的设备,每个应用都在棋自己的进程中运行,并且有其自己的Android Runtime(ART)实例.
原生C/C++库
许多核心Android系统组件和服务(例如ART和HAL)构建自原生代码,需要以C和C++编写的原生库.
Java API 框架
可通过以Java语言编写的API使用Android OS 的整个功能集.
系统应用
Android随附一套用于电子邮件,短信,日历,互联网浏览和联系人等的核心应用.
Jetpack是一个开发者组件工具集,主要目的是帮助我们写出更加简洁的代码,简化开发过程.Jetpack中的组件,大部分不依赖任何Android系统版本,这些组件通常定义在AndroidX库中,并且拥有非常好的向下兼容性.

11.1 ViewModel
ViewModel是用来专门存放于界面相关数据的,尽量将数据存放到ViewModel中,减少Activity的逻辑. ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续存在。下面是ViewModel的生命周期

11.2 Lifecycles
让任何类都能轻松感知到Activity的生命周期.
11.3 LiveData
LiveData是Jetpack提供的一种响应式编程组件,它可以包含任何类型的数据,并在数据发生变化的时候通知给观察者. LiveData是Activity与ViewModel之间通信的桥梁,它内部靠的是Lifecycles组件来自我感知生命周期的变化,从而在Activity销毁的时候及时释放引用,避免产生内存泄露.
11.4 Room
Android官网的ORM框架(对象关系映射).
11.4.1 Entity
定义封装实际数据的实体类,每个视图类都会在数据库中有一张对应的表,并且表中的列是根据实体类中的字段自动生成的.
11.4.2 Dao
数据访问对象,通常会在这里对数据库的各项操作进行封装.
11.4.3 Database
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。







既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)

架构师筑基包括哪些内容
我花了将近半个月时间将:深入 Java 泛型.、注解深入浅出、并发编程.、数据传输与序列化、Java 虚拟机原理、反射与类加载、高效 IO、Kotlin项目实战等等Android架构师筑基必备技能整合成了一套系统知识笔记PDF,相信看完这份文档,你将会对这些Android架构师筑基必备技能有着更深入、更系统的理解。
由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容
注:资料与上面思维导图一起看会更容易学习哦!每个点每个细节分支,都有对应的目录内容与知识点!


这份资料就包含了所有Android初级架构师所需的所有知识!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
都有对应的目录内容与知识点!**
[外链图片转存中…(img-MgZaBsNO-1712478027113)]
[外链图片转存中…(img-2yJDlQKO-1712478027113)]
这份资料就包含了所有Android初级架构师所需的所有知识!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
更多推荐

所有评论(0)