Android & Kotlin : 困惑解答

  1. 如何绑定布局(使用setContentView 与 binding绑定控件的区别)
  2. MVVM模式

使用setContentView 与 binding绑定控件的区别

setContentView(R.layout.activity_main)

在kotlin中可以使用原生的setContentView绑定布局,但是他需要手动查找控件来对控件进行操作,一般适用于加载frame空布局使用比较方便
使用DataBinding
1.在modul 的gradle中打开开关

   dataBinding {
        enabled true
    }
    }

2.使用layout作为根标签 包裹布局文件

注意现在布局的根标签是layout,否则在build时候不能在out目录下输出binding类
还需要注意的是在布局中的数据要绑定对应的数据
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bind="http://schemas.android.com/apk/res-auto">
    <data>
        <import type="android.view.View"/>
        <variable name="viewModel" type="com.coolweather.coolweatherjetpack.ui.weather.WeatherViewModel" />
        <variable name="resId" type="Integer" />
        <variable name="init" type="Boolean" />
    </data>
...

3.在代码中使用DataBinding

private val binding by lazy { DataBindingUtil.setContentView<ActivityWeatherBinding>(this, R.layout.activity_weather) }
 binding.viewModel = viewModel
        binding.resId = R.color.colorPrimary
        binding.lifecycleOwner = this
        navButton.setOnClickListener {
            drawerLayout.openDrawer(GravityCompat.START)
        }

这个是在kotlin中加载布局简单的方式,可以直接使用binding. 来直接调用布局的data标签,控件可以直接使用而无需使用findViewById,来进行查找定义(包括嵌套的二级控件也是直接拿来使用即可)

【ERROR】
Cannot find the setter for attribute ‘bind:showForecast’ with parameter type com.example.jingjetpack.model.weather.Weather on android.widget.LinearLayout.
![报错](https://img-blog.csdnimg.cn/20191023131344384.png

【解决方案】
首先在app的目录下的build.gradle中要加入apply plugin: ‘kotlin-kapt’
apply plugin: ‘kotlin-kapt’
【ERROR】
Incremental annotation processing requested, but support is disabled because the following processors are not incremental: android.databinding.annotationprocessor.ProcessDataBinding
【解决方案】
这是 kotlin-gradle-plugin 1.3.50 版本的一个bug。
gradle.properties 文件中添加 kapt.incremental.apt = false 来禁用增量注解处理 或者 将 kotlin_version 版本降低。
【问题】如何查看kotlin-gradle-plugin的版本号
工程-builde.gradle-------------换成1.3.20
在这里插入图片描述【ERROR】
E:\WorkSpace\jingJetpack\app\build\generated\source\kapt\debug\com\example\jingjetpack\DataBinderMapperImpl.java:9: 错误: 找不到符号
import com.example.jingjetpack.databinding.ActivityWeatherBindingImpl;
^
符号: 类 ActivityWeatherBindingImpl
位置: 程序包 com.example.jingjetpack.databinding
viewModel.refreshing.getValue() is a boxed field but needs to be un-boxed to execute bind:refreshing. This may cause NPE so Data Binding will safely unbox it. You can change the expression and explicitly wrap viewModel.refreshing.getValue() with safeUnbox() to prevent the warning
【解决方案】

const val 和val 的区别

const 必须修饰val
const 只允许在top-level级别*(这个目前不知道是啥意思)*和object中声明,使用方式如下

 - 在ChooseAreaFragment这个类中声明
  companion object {
        const val LEVEL_PROVINCE = 0
        const val LEVEL_CITY = 1
        const val LEVEL_COUNTY = 2
    }

const val 可见性为public final static,可以直接访问。
val 可见性为private final static,并且val 会生成方法getNormalObject(),通过方法调用访问。

2.在ChooseAreaViewModel这个类中直接调用,而不需要使用函数方法调用
  fun getProvinces() {
        currentLevel.value = LEVEL_PROVINCE
      ...
    }

进程,线程和协程的区别

  • 协程是轻量级的线程.
    线程是由系统调度的,线程切换和线程阻塞的开销都比较大.而协程依赖于线程,但是协程挂起时不需要阻塞线程,几乎是无代价的,协程是由开发者控制的.所以协程也像用户态的线程,非常轻量级,一个线程中可以创建任意个协程
  • 协程是编译器级的,线程和进程是操作系统级的.
    线程和进程是os通过调度算法,保存当前的上下文,然后从上次暂停的地方再次开始计算,重新开始的地方不可预期,每次CPU计算的指令数量和代码跑过的CPU时间是相关的,跑到os分配的cpu时间到达后就会被os强制挂起。
    协程是编译器的魔术,通过插入相关的代码使得代码段能够实现分段式的执行,重新开始的地方是yield关键字指定的,一次一定会跑到一个yield对应的地方.
  • 对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。
    协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。协程能保留上一次调用时的状态,不需要像线程一样用回调函数,所以性能上会有提升。缺点是本质是个单线程,不能利用到单个CPU的多个核
    协程是跑在线程上的,一个线程可以同时跑多个协程,每一个协程则代表一个耗时任务,我们手动控制多个协程之间的运行、切换,决定谁什么时候挂起,什么时候运行,什么时候唤醒,而不是 Thread 那样交给系统内核来操作去竞争 CPU 时间片
  • 协程在线程中是顺序执行的,既然是顺序执行的那怎么实现异步?
    Thread中我们有阻塞、唤醒的概念,协程里同样也有,挂起等同于阻塞,区别是 Thread 的阻塞是会阻塞当前线程的(此时线程只能空耗 cpu 时间而不能执行其他计算任务,是种浪费),而协程的挂起不会阻塞线程。当线程接收到某个协程的挂起请求后,会去执行其他计算任务,比如其他协程。协程通过这样的手段来实现多线程、异步的效果,在思维逻辑上同Thread 的确有比较大的区别,大家需要适应下思路上的变化
    suspend 关键字
    协程天然亲近方法,协程表现为标记、切换方法、代码段,协程里使用suspend关键字修饰方法,该方法可以被协程挂起,没用suspend修饰的方法不能参与协程任务,suspend修饰的方法只能在协程中只能与另一个suspend修饰的方法交流

let 函数的使用

在这里插入图片描述
当前类是ChooseAreaViewModel,仔细瞅一下 it代指的对象
如何用it指代的作用域是其他类的,自行体会

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值