1, 2 -> println(“1 or 2”)
in 1…2 -> println(“in 1 and 2”)
else -> {
println(“nothing”)
}
}
/*
10.6 单例
*/
println(Utils1.label)
println(Utils2.hello())
/*
10.7 static
*/
println(CompanionTest.name)
println(CompanionTest.run())
/*
10.8 getter and setter
*/
val getterAndsetter = KotlinGetterAndSetter()
getterAndsetter.x = 100
println(“getter and setter:” + getterAndsetter.x)
//getter and setter 二次赋值
val person = Person()
println(“name:${person.name}”)
person.name = “hello world”
println(“name:${person.name}”)
person.age = -1
println(“name:${person.age}”)
/* 11. 内联函数
apply let run with also
函数体对象 this it this this it
对象是否可省 可 不可 可 可 不可
返回值 必有,当前对象 最后一行,可有可无 最后一行,可有可无 最后一行,可有可无 必有,当前对象
可否判空 可以 可以 可以 不可以 可以
*/
//let -> 闭包内使用it作为当前这个对象的参数; 返回值是函数最后一行, 或者return语句
fun letTest(): Int {
// fun <T, R> T.let(f: (T) -> R): R { f(this)}
“letTest”.let {
println(it)
return 1
}
}
println(letTest())
//apply -> 闭包内可以任意调用此对象; 并且最终也会返回此对象
fun applyTest() {
// fun T.apply(f: T.() -> Unit): T { f(); return this }
ArrayList().apply {
add(“applyTest”)
println(“this = $this, size = $size”)
}.let { println(it) }
}
applyTest()
// apply with null and nonnull
val strJim: String? = null
strJim?.apply {
println(“apply with nonnull”)
} ?: strJim.apply {
println(“apply with null”)
}
//with -> 闭包内可以任意调用此对象; 返回值是函数最后一行, 或者return语句
fun withTest() {
// fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
with(ArrayList()) {
add(“withTest”)
println(“this = $this, size = $size”)
}.let { println(it) }
}
withTest()
//run -> run只接收一个lambda函数为参数; 返回值是函数最后一行, 或者return语句
fun runTest() {
// fun <T, R> T.run(f: T.() -> R): R = f()
“runTest”.run {
println("this = " + this)
}.let { println(it) }
}
runTest()
//run用来判空
val s = null
s?.run {
} ?: run {
println(“use run to identify null”)
}
//also
fun alsoTest() {
val car = Car(“Benz”)
car.also {
it.name = “BMW”
}
println(“car’s name is ${car.name}”)
}
alsoTest()
/*
- 其它
*/
//test anonymous inner class about interface
callback.getName(123)
//@JvmOverloads, 声明多个参数的构造函数
val animal = Animal()
animal.func(“dog”)
animal.func(“dog”, 2)
animal.func(“dog”, 2, “New York”)
//lambda表达式
val lambdaTest1 = LambdaTest1()
lambdaTest1.setTheCallBack(object : CallBack {
override fun getName(id: Int) {
println(“getName”)
}
})
//if the callback defined in java
lambdaTest1.setTheCallBackFromJava(CallBackFromJava {
println(“getName”)
})
val lambdaTest2 = LambdaTest2()
lambdaTest2.setCallBack({ id -> println(“getName”) })
lambdaTest2.setCallBack { id -> println(“getName”) }
lambdaTest2.setCallBack { println(“getName”) }
//lambda使用下划线_, 没有用到的就用_代替
val aa = mapOf(1 to “a”, 2 to “B”)
aa.forEach { (_, value) -> println(“value:$value”) }
// chain use
var list = arrayOf(“java”, “c++”, “Android”, “Kotlin”, “iOS”)
list.map {
“Hello $it”
}.filter {
!it.contains(“c”)
}.forEach {
println(it)
}
}
//new a interface
private val callback = object : CallBack {
override fun getName(id: Int) {
println(“CallBack -> getName”)
}
}
/*
Object: 单例, Object修饰的类为静态类, 里面的方法和变量都是静态的
*/
object Utils1 {
val label: String
get() {
if (true)
return “here is singleton fun”
else
return “”
}
}
object Utils2 {
fun hello() {
println(“here is an object demo”)
}
}
/*
Interface
*/
//interface CallBack {
// fun getName(id: Int)
//}
interface CallBack2 {
fun getName(id: Int)
fun getVersion() = 1 // can offer non-abstract method
}
/*
companion object:伴生对象,相当于java中的static
*/
class CompanionTest {
companion object { //一个类中只能存在一个伴生对象
val name: String = “Vincent”
fun run() {
println(“I am running!”)
}
}
}
/*
getter and setter: 自带, 默认隐藏
*/
class KotlinGetterAndSetter {
var x: Int = 0
set(value) {
field = value
}
get() = field
}
class Person {
var name: String = “Tom”
set(value) {
field = value
}
get() = field.toUpperCase()
var age: Int = 100
set(value) {
if (value < 0) {
field = 0
} else {
field = value
}
}
get() = field
}
/*
@JvmStatic and @JvmField,主要是方便java调用,不用再在java中写.INSTANCE调用kotlin代码
*/
open class JvmClass {
companion object {
@JvmField
val name: String = “jvm test”
@JvmStatic
fun method() {
println(“call method”)
}
}
}
class Animal {
//define multiple constructor
@JvmOverloads
fun func(a: String, b: Int = 0, c: String = “abc”) {
}
}
class Car(var name: String) {
}
class LambdaTest1 {
var callback: CallBack? = null
var callbackfromjava: CallBackFromJava? = null
fun setTheCallBack(callback: CallBack) {
this.callback = callback
}
fun setTheCallBackFromJava(callbackfromjava: CallBackFromJava) {
this.callbackfromjava = callbackfromjava
}
}
class LambdaTest2 {
lateinit var callback: (CallBack) -> Unit
fun setCallBack(callback: (CallBack) -> Unit) {
this.callback = callback
}
}
class User(var name: String, var age: Int) {
}
=============================================================================
fun main(args: Array) {
/*
- lambda表达式
*/
//(1) kotlin中lambda表达式定义在{}中
//(2) 其参数(如果存在)在 -> 之前声明(参数类型可以省略)
//(3) 函数体(如果存在)在 -> 后面
//源代码:无参
fun l1() {
println(“无参数”)
}
//lambda表达式: 以值的形式传递
val l1 = { println(“无参数”) }
//调用
l1()
//源代码:有参
fun l2(x: Int, y: String) {
println(y.length + x)
}
//lambda表达式: 以值的形式传递
val l2 = { x: Int, y: String -> println(y.length + x) }
//调用
l2(1, “Mike”)
//lambda表达式可以直接通过run运行
run { l2(1, “tom”) }
//lambda简化过程
val people = listOf(User(“张三”, 18), User(“李四”, 20))
//1.1 函数只有lambda一个实参
//原始完整代码
println(“年纪最大:” + people.maxBy({ user: User -> user.age }))
//step1:如果lambda表达式是函数调用的最后一个实参,它可以放在括号外面
println(“年纪最大:” + people.maxBy() { user: User -> user.age })
//step2: 当lambda是函数唯一的实参时,可以去掉函数调用的括号
println(“年纪最大:” + people.maxBy { user: User -> user.age })
//step3:如果lambda的参数的类型可以推导,那么可以省略参数的类型
println(“年纪最大:” + people.maxBy { user -> user.age })
//step4:对于lambda中一个参数时,可以使用默认参数名称it来代替命名参数,并且lambda的参数列表可以简化,省略参数列表和->
println(“年纪最大:” + people.maxBy { it.age })
//1.2 函数有除了lambda外多个实参
fun lambdaTest1(a: Int, b: (String) -> String) {
println(“$a + ${b(a.toString())}”)
}
fun lambdaTest2(b: (String) -> String, a: Int) {
println(“$a + ${b(a.toString())}”)
}
lambdaTest1(11) {
“hello: $it”
}
lambdaTest2({ “hello: $it” }, 22)
//定义匿名函数,赋值给test变量
var test = fun(x: Int, y: Int): Int {
return x + y
}
//通过test调用匿名函数
println(test(2, 4))
/*
- 函数作为参数传递, 可以用作回调: T.()->Unit 和 ()->Unit
接受函数作为参数或者返回一个函数的函数就叫做高阶函数
*/
//() -> Unit//表示无参数无返回值的Lambda表达式类型
//(T) -> Unit//表示接收一个T类型参数,无返回值的Lambda表达式类型
//(T) -> R//表示接收一个T类型参数,返回一个R类型值的Lambda表达式类型
//()->Unit
//2.1 不带参数和返回值的函数作为形参
fun action0(method: () -> Unit) {
method()
println(“this is action0”)
}
fun method0() {
println(“this is method0 which is invoked”)
}
action0 {
println(“this is action0”)
}
fun action1(first: Int, method: () -> Unit) {
method()
println(“this is action1”)
}
//format->step1
action1(1, {
println(“第1种写法”)
})
//format->step2
action1(1) {
println(“第2种写法”)
}
val method: () -> Unit = {
println(“第3种写法”)
}
action1(1, method)
//2.2 带参数和返回值的函数作为形参
fun method1(msg1: Int, msg2: Int): Int {
println(“this is method1”)
return msg1 + msg2;
}
fun getResult1(
arg01: Int,
arg02: Int,
method: (arg1: Int, arg2: Int) -> Int
) {
println(“----->msg:before”)
val ret = method(arg01, arg02);
println(“----->msg:after = $ret”)
}
println(getResult1(1, 2, ::method1))
//T.()->Unit
fun getResult3(
method: Test.() -> Unit
) {
println(“----->msg:before”)
val test1 = Test()
test1.apply(method)
println(“----->msg:after ${test1.a}”)
}
println(
getResult3(
{
a = “Tim”
})
)
//2.3 函数作为参数, 指定加载位置和时机
var host = false
fun isHost() = host
suspend fun getFromNet() {
withContext(Dispatchers.IO) {
delay(1000)
host = true
}
}
fun load(checkHost: () -> Boolean) {
GlobalScope.launch() {
getFromNet()
if (checkHost.invoke()) println(“yes, it’s the host”) else print(“no, it’s not the host”)
}
}
load { isHost() }
/*
3.1 类委托
*/
val b = BaseImpl(10)
Derived(b).print() // 输出 10
Derived(b).otherPrint() //输出other
/*
3.2 属性委托
*/
val isLogin: Boolean by DerivedProperty(“tom”)
if (isLogin) {
println(“this is a property when invoked”)
}
/*
- 协程
*/
// 4.1 RxJava和协程的区别
fun getUser(): Observable {
val random = Random()
return Observable
.create { emitter: ObservableEmitter ->
//模拟网络请求
println("I’m doing network,CurrentThread is " + Thread.currentThread().name + “…”)
Thread.sleep(1000)
if (random.nextBoolean()) {
emitter.onNext(“Jack”)
} else {
emitter.onError(TimeoutException(“Net Error!”))
}
}
.subscribeOn(Schedulers.io())//指定网络请求在IO线程
}
fun rxjava() {
getUser()
.subscribe(object : Observer {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: String) {
println(t)
}
override fun onError(e: Throwable) {
}
})
Thread.sleep(2000)//延时2s,避免主线程销毁
}
//run
rxjava()
/* 4.2
- 可在全局创建协程: launch和runBlocking
(1)launch是非阻塞的;
(2)runBlocking是阻塞的;
- 可返回结果的协程: withContext和async
(1)withContext与async都可以返回耗时任务的执行结果;
(2)多个withContext任务是串行的, withContext可直接返回耗时任务的结果;
(3)多个async任务是并行的, async返回的是一个Deferred, 需要调用其await()方法获取结果;
*/
//4.2.1.1: launch
GlobalScope.launch {
delay(1000)
println(“1.执行launch, [当前线程为:${Thread.currentThread().name}]”)
}
println(“2.Run launch, [当前线程为:${Thread.currentThread().name}]”)
//指定运行在主线程中
// GlobalScope.launch(Dispatchers.Main) { println(Thread.currentThread().name) }
//4.2.1.2: runBlocking
runBlocking {
delay(500) //延时500ms
println(“1.执行runBlocking, [当前线程为:${Thread.currentThread().name}]”)
}
println(“2.Run runBlocking, [当前线程为:${Thread.currentThread().name}]”)
//4.2.2.1: withContext
GlobalScope.launch {
val time1 = System.currentTimeMillis()
val task1 = withContext(Dispatchers.IO) {
delay(2000)
println(“1.执行withContext-task1… [当前线程为:${Thread.currentThread().name}]”)
“one” //返回结果赋值给task1
}
val task2 = withContext(Dispatchers.IO) {
delay(1000)
println(“2.执行withContext-task2… [当前线程为:${Thread.currentThread().name}]”)
“two” //返回结果赋值给task2
}
println(“执行withContext-task1 = $task1 , 执行withContext-task2 = $task2 , 耗时 S y s t e m . c u r r e n t T i m e M i l l i s ( ) − t i m e 1 m s [ 当前线程为: {System.currentTimeMillis() - time1} ms [当前线程为: System.currentTimeMillis()−time1ms[当前线程为:{Thread.currentThread().name}]”)
}
//4.2.2.1: async
GlobalScope.launch {
val time1 = System.currentTimeMillis()
val task1 = async(Dispatchers.IO) {
delay(2000)
println(“1.执行async-task1… [当前线程为:${Thread.currentThread().name}]”)
“one” //返回结果赋值给task1
}
val task2 = async(Dispatchers.IO) {
delay(1000)
println(“2.执行async-task2… [当前线程为:${Thread.currentThread().name}]”)
“two” //返回结果赋值给task2
}
println(“执行async-task1 = ${task1.await()} , async-task2 = ${task2.await()} , 耗时 S y s t e m . c u r r e n t T i m e M i l l i s ( ) − t i m e 1 m s [ 当前线程为: {System.currentTimeMillis() - time1} ms [当前线程为: System.currentTimeMillis()−time1ms[当前线程为:{Thread.currentThread().name}]”)
}
//4.2.3: 线程切换
GlobalScope.launch(Dispatchers.Unconfined) {
println(“Dispatchers.Unconfined: ${Thread.currentThread().name}”)//输出false
//上下文切换到主线程
GlobalScope.launch(Dispatchers.IO) {
println(“Dispatchers.IO: ${Thread.currentThread().name}}”)//输出true
}
}
//4.3 Scope: 协程作用范围
//GlobalScope:表示此协程的生命周期随应用程序的生命周期, 没有和生命周期组件相关联
//CoroutineScope:在应用中具有生命周期的组件应该实现CoroutineScope接口, 并负责该组件内 Coroutine 的创建和管理;
// 以Activity为例, 比如标准库中定义的MainScope(), 另外参考KotlinInAndroid中的ScopedActivity和SimpleScopedActivity
//viewModelScope(androidx.lifecycle.viewModelScope, androidx.lifecycle.lifecycleScope)
/*
- 扩展函数
*/
fun ExtClass.foo() = println(“ext”) // when the same as the member foo
fun ExtClass.foo(para: Int) = println(“ext”)
ExtClass().foo()
ExtClass().foo(0)
/*
- 闭包:函数中包含函数
*/
val plus = { x: Int, y: Int -> println(“$x plus $y is ${x + y}”) }
val hello = { println(“Hello Kotlin”) }
fun closure(args: Array) {
{ x: Int, y: Int ->
println(“$x plus $y is ${x + y}”)
}(2, 8) // 自执行的闭包
plus(2, 8)
hello()
}
/*
- 单例
*/
println("Singleton: " + Single.get().pro)
/*
- Kotlin海量操作符, 替代RxJava操作符
*/
fun rxjavaOperators() {
//定义一个数组
val index = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
// Observable
// .just(index)
// .flatMap(object : Function<List, Observable> {
// override fun apply(f: List): Observable {
// return Observable.fromIterable(f)
// }
// })
// .filter(object : Predicate {
// override fun test(p: Int): Boolean {
// return p % 2 == 0
// }
// })
// .map(object : Function<Int, String> {
// override fun apply(f: Int): String {
// return “[rxjava]String” + f
// }
// })
// .subscribe(object : Consumer {
// override fun accept(t: String?) {
// println(t)
// }
// })
Observable
.just(index)
.flatMap { Observable.fromIterable(it) }
.filter { it % 2 == 0 }
.map { “[rxjava]String$it” }
.subscribe { println(it) }
}
rxjavaOperators()
fun kotlinOperators() {
val index = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
index.filter { it % 2 == 0 }
.map { “[kotlin]String$it” }
.also { println(it) }
}
kotlinOperators()
//将主线程延迟退出, 保证上面延时操作完成
Thread.sleep(5000)
}
class ExtClass {
fun foo() = println(“origin”)
}
class Test {
var a: String? = null
}
// 创建接口
interface Base {
fun print()
}
// 实现此接口的委托类
class BaseImpl(private val x: Int) : Base {
override fun print() {
println(x)
}
}
// 通过关键字 by 建立代理类, 能够调用委托类已实现的方法和属性,不需再实现print()方法
class Derived(b: Base) : Base by b {
fun otherPrint() {
println(“other”)
}
}
class DerivedProperty(private val name: String) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
println(“this is a property delegate: $name”)
return when (name) {
“tom” -> true as T
“jerry” -> false as T
else -> false as T
}
return true as T
}
}
class Single private constructor() {
val pro: Boolean = false
companion object {
fun get(): Single {
return Holder.instance
}
}
private object Holder {
val instance = Single()
}
}
===============================================================================
class KotlinInAndroid : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//1. 控件直接用id, 不再使用findviewbyid
btn_1.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
toastMe()
}
})
btn_1.setOnClickListener { toastMe() } //lambda表达式更加简洁
//2. 控件自定义方法
iv_1.loadUrl(“https://www.baidu.com/img/bd_logo1.png”)
//3. 扩展函数: 控件自定义方法可放在单独的类中
toast(“a toast”)
toast(“a toast”, Toast.LENGTH_LONG)
//4. 协程
//两个耗时操作,必须要在异步线程实现处理,处理完成后需要在主线程输出结果
//way1:
MainScope().launch {
val startTime = System.currentTimeMillis()
println(“[way1]tag1:” + Thread.currentThread().name)
val text1 = withContext(Dispatchers.IO) {
println(“[way1]tag2:” + Thread.currentThread().name)
delay(1000)
"Hello "
}
val text2 = withContext(Dispatchers.IO) {
println(“[way1]tag3:” + Thread.currentThread().name)
delay(1000)
“World!”
}
println(“[way1]tag4:” + Thread.currentThread().name)
println(text1 + text2)
println(“[way1]耗时:” + (System.currentTimeMillis() - startTime))
}
//way2:
MainScope().launch {
val startTime = System.currentTimeMillis()
println(“[way2]tag1:” + Thread.currentThread().name)
val text1 = getHello(“[way2]”)
val text2 = getWorld(“[way2]”)
println(“[way2]tag4:” + Thread.currentThread().name)
println(text1 + text2)
println(“[way2]耗时:” + (System.currentTimeMillis() - startTime))
}
//way3:异步,不阻塞
MainScope().launch {
val startTime = System.currentTimeMillis()
println(“[way3]tag1:” + Thread.currentThread().name)
val text1 = async { getHello(“[way3]”) }
val text2 = async { getWorld(“[way3]”) }
println(“[way3]tag4:” + Thread.currentThread().name)
println(text1.await() + text2.await())
println(“[way3]耗时:” + (System.currentTimeMillis() - startTime))
}
//way4:
GlobalScope.launch(Dispatchers.Main) {
var name = getResultFromNet()
showResult(name)
}
//5. set赋值, text替换setText
btn_1.text = “click me…”
//6. scoped activity
btn_2.setOnClickListener {
startActivity(Intent(this, SimpleScopedActivity::class.java))
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

更多学习和讨论,欢迎加入我们!
有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
这里有2000+小伙伴,让你的学习不寂寞~·
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
“[way3]”) }
val text2 = async { getWorld(“[way3]”) }
println(“[way3]tag4:” + Thread.currentThread().name)
println(text1.await() + text2.await())
println(“[way3]耗时:” + (System.currentTimeMillis() - startTime))
}
//way4:
GlobalScope.launch(Dispatchers.Main) {
var name = getResultFromNet()
showResult(name)
}
//5. set赋值, text替换setText
btn_1.text = “click me…”
//6. scoped activity
btn_2.setOnClickListener {
startActivity(Intent(this, SimpleScopedActivity::class.java))
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-bxCZiusE-1713518866285)]
[外链图片转存中…(img-NAs771CV-1713518866287)]
[外链图片转存中…(img-IBcAqLu1-1713518866288)]
[外链图片转存中…(img-1tJMCZS6-1713518866289)]
[外链图片转存中…(img-twrLvwh9-1713518866290)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

[外链图片转存中…(img-jQe5uo43-1713518866291)]
更多学习和讨论,欢迎加入我们!
有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
这里有2000+小伙伴,让你的学习不寂寞~·
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!