GVKun编程网logo

记录学习在Android中使用kotlin.coroutines(android kotlin 教程)

10

关于记录学习在Android中使用kotlin.coroutines和androidkotlin教程的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于AndroidKotlinCorouti

关于记录学习在Android中使用kotlin.coroutinesandroid kotlin 教程的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android Kotlin Coroutines ktx扩展、Android Kotlin RXKotlin Room - 错误 Kotlin.unit、android – Kotlin coroutine吞下异常、android – 使用Kotlin进行数据绑定会导致资源$NotFoundException等相关知识的信息别忘了在本站进行查找喔。

本文目录一览:

记录学习在Android中使用kotlin.coroutines(android kotlin 教程)

记录学习在Android中使用kotlin.coroutines(android kotlin 教程)

学习使用kotlin中的coroutines

学习背景

  在学习第一行代码时的Service中的启动子线程来完成异步处理时,书中提到了使用AsyncTask来更方便地操作UI。
  但由于Context泄露、回调遗漏、configuration变化导致奔溃、平台差异性等原因,AsyncTask在Android 11 中被正式弃用。

Google官方提供了两种替换思路:

  1. 使用java.util.concurrent下的包,如Executor、ThreadPoolExecutor、FutureTask
  2. 使用kotlin的Coroutines——协程
    既然是在学习kotlin的Android编程,总不能照学书中已经过时的内容(Android更新换代也太快了吧555我要回去写后端了)此处就又给自己挖了一个坑啦。

学习路线

  通过查阅资料如何正确的在Android上使用协程中,我得到了初步的学习思路:先按照Kotlin官方文档提供的example学习协程的概念以及初步使用。当然,在上文中也提到了一般不建议直接照着官方文档的方式使用协程,那么接下来我会再阅读一下文中提到的三篇文章试试看:
  1.在 Android 上使用协程(一):Getting The Background
  2.在 Android 上使用协程(二):Getting started
  3.在 Android 上使用协程(三) :Real Work

kotlin官方文档学习之路

添加依赖

  从README文档中可以得知kotlin在不同的环境中有不同的引入依赖方式,在安卓的开发环境中只需通过向项目app文件夹的build.gradle中添加依赖

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'  即可

协程基础

   文章中介绍了协程是轻型的线程,并且可以使用一系列的Coroutinescope启动(例如GlobalScope);然后介绍了delaythread.sleep()的区别,以及如何清晰地区分阻塞函数与非阻塞函数。类似于delay的挂起函数只能在协程中使用。

   之后通过设置一个对象,接收了一个GlobalScope.launch返回的Lambda,可以通过调用join()的方式在合适的时候启动该协程。

runBlockingcoroutinescope 作用域的区别

   两个种类的代码块都可以等待它们内部的代码执行完成再进行后续操作。区别在于:

  • runBlocking 方法会阻塞当前线程,
  • coroutinescope 方法仅仅是悬挂并释放底层线程供其他区域使用。
  • 因此runBlocking是一个常规函数,coroutinescope为悬挂函数。
#例1
fun main() = runBlocking {
    runBlocking {
        launch {
            delay(300)
            println("Task from ronBlocking nested launch"  + order.toString())
            order += 1
        }
        delay(200)
        println("Task from runBlocking" + order.toString())
        order += 1
    }

    coroutinescope {
        launch {
            delay(500)
            println("Task from nested launch"  + order.toString())
            order += 1
        }

        delay(100)
        println("Task from coroutine scope"  + order.toString())
        order += 1
    }

    println("Coroutine scope is over"  + order.toString())
    order += 1
}

# 结果
Task from runBlocking1
Task from ronBlocking nested launch2
Task from coroutine scope3
Task from nested launch4
Coroutine scope is over5

#例2
fun main() = runBlocking {
    launch {
        delay(300)
        println("Task from runBlocking" + order.toString())
        order += 1
        launch {
            delay(200)
            println("Task from ronBlocking nested launch"  + order.toString())
            order += 1
        }
    }

    coroutinescope {
        launch {
            delay(500)
            println("Task from nested launch"  + order.toString())
            order += 1
        }

        delay(100)
        println("Task from coroutine scope"  + order.toString())
        order += 1
    }

    println("Coroutine scope is over"  + order.toString())
    order += 1
}
# 结果
Task from coroutine scope1
Task from runBlocking2
Task from nested launch3
Coroutine scope is over4
Task from ronBlocking nested launch5

  从例1中可以看出内部的runBlocking代码块阻塞了main()线程,而从例2中可以发现delay只会阻塞它所在的线程/协程。

GlobalScope :全局协程

   由GlobalScope.launch 启动的协程相当于守护进程,生存周期为当前的Context的生存周期。

Android Kotlin Coroutines ktx扩展

Android Kotlin Coroutines ktx扩展

本篇文章主要讲的是,kotlin 协程在 ktx 上的扩展

lifecycle 扩展
对于 lifecycle 的扩展,已经在 以前的文章中讲过了

主要的依赖

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"

viewModel 扩展
对于 viewModel 的扩展,已经在 以前的文章中讲过了

主要的依赖

implementation ''androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1''

liveData 扩展
主要的依赖

 implementation ''androidx.lifecycle:lifecycle-livedata-ktx:2.2.0''

官网链接如下:

具体使用举例如下:

class MainActivity : AppCompatActivity() {

    val user: LiveData<String> = liveData {
        //模拟网络请求
        var user = getUser()

        if (user == "ok") {
            //模拟请求成功
            emit("ok")
        } else {
            //模拟请求失败
            emit("failed")
        }
    }

    /**
     * 模拟网络请求
     */
    suspend fun getUser(): String {
        var ret = withContext(Dispatchers.Default) {
            "ok"
        }
        return ret
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        user.observe(this, {
            Log.d("yy--", "name1:$it")
        })

    }
}

Android Kotlin RXKotlin Room - 错误 Kotlin.unit

Android Kotlin RXKotlin Room - 错误 Kotlin.unit

如何解决Android Kotlin RXKotlin Room - 错误 Kotlin.unit?

我想通过循环数组向房间数据库做一个简单的插入数据。 我使用 RXKotlin 来迭代数组 我有一个这样的数组:

fun defaultDataCategory() : ArrayList<CategoryModel>{
        var cat: CategoryModel
        var catArrayList: ArrayList<CategoryModel> = ArrayList(0)
        val date: Int = Calendar.DATE
        val formatedDate = SimpleDateFormat("yyyy-MM-dd").format(Date())
        val formatedTime = SimpleDateFormat("HH:mm").format(Date())
        val DateTime = "$formatedDate  $formatedTime"

        catArrayList.add(
            CategoryModel(
                1,"Personal",true,"Red",Converter.toDate(Calendar.getInstance().timeInMillis),"system","system"
            )
        )

        catArrayList.add(
            CategoryModel(
                2,"Work","Blue","system"
            )
        )

        catArrayList.add(
            CategoryModel(
                3,"Home","Purple","system"
            )
        )

        catArrayList.add(
            CategoryModel(
                4,"Learn","Yellow","system"
            )
        )
       return catArrayList
    }

我像这样用 RXKotlin 循环了一个数组

var catArrayList: ArrayList<CategoryModel> = DefaultData.defaultDataCategory()

        catArrayList.toObservable()
            .subscribeBy(  // named arguments for lambda Subscribers
                onNext = { homeviewmodel.insertCategory(it) },onError = { Log.e("error insert=",it.printstacktrace().toString()) },onComplete = { Log.e("complete insert=","complete insert") }
            )

我得到了一个错误“kotlin.unit”。

Error RXKotlin

如何使用 RXKotlin 迭代数组并插入房间数据库?

解决方法

试试

Observable.fromIterable(catArrayList).subscribeBy {...}

android – Kotlin coroutine吞下异常

android – Kotlin coroutine吞下异常

关于异常处理如何与协同程序一起使用,我感到非常困惑.

我希望有一个挂起函数链可以像同步代码一样在它们之间传递异常.因此,如果说Retrofit抛出IOException,我可以在挂起函数链的开头处理该异常,例如在演示者中向用户显示错误.

我做了这个简单的例子来尝试协同程序但是如果我取消注释要么在Exception无法运行之后抛出异常调用代码但是Exception不会使应用程序崩溃.

package com.example.myapplication

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Button
import android.widget.TextView
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text = findViewByIdetonClickListener {
            launch {
                count++
//                throw Exception("Boom")
                val string = delayedStringOfInt(count)
                runOnUiThread { text.text = string }
            }
        }
    }

    suspend fun delayedStringOfInt(int: Int): String {
        delay(1000)
//        throw Exception("Boom")
        return int.toString()
    }
}

我尝试过使用async和CoroutineExceptionHandler.

最佳答案
使用异步时,您应该在某处等待结果,这样您就不会丢失任何异常.

android – 使用Kotlin进行数据绑定会导致资源$NotFoundException

android – 使用Kotlin进行数据绑定会导致资源$NotFoundException

上下文

我使用library利用数据绑定通过其BindingAdapter在任何View上定义自定义属性:

@BindingAdapter({"attribute"})
public static void bindAttribute(@NonNull View view, String attribute) 
{...}

这允许我定义库在运行时处理的自定义属性:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:algolia="http://schemas.android.com/apk/res-auto">

    <LinearLayout
        <!-- ... -->
        android:orientation="horizontal">

        <ImageView
            <!-- ... -->
            algolia:attribute='@{"objectID"}'/>
    </LinearLayout>
</layout>

然后将此视图用作子类RecyclerView的ViewHolder的itemLayout.
所有这些在我的Java应用程序中都能正常工作.

问题

我开始在Kotlin建立一个类似的应用程序.为了使用数据绑定,我按照documentation’s guide添加了以下内容:

// ./app/build.gradle
apply plugin: 'kotlin-kapt'

android {
    dataBinding {
        enabled true
    }
...
}
dependencies {
    kapt "com.android.databinding:compiler:$plugin_version"
...
}
// ./build.gradle
ext.plugin_version = '2.3.3'
dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
... 
}

但是,运行应用程序并显示RecyclerView会在其onCreateViewHolder中触发异常:

08-31 14:32:00.511 22067-22067/com.algolia.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.algolia.app, PID: 22067
android.content.res.Resources$NotFoundException: Resource ID #0xffffffd6
at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:190)
at android.content.res.Resources.loadXmlResourceParser(Resources.java:2105)
at android.content.res.Resources.getLayout(Resources.java:1119)
at android.view.LayoutInflater.inflate(LayoutInflater.java:424)
at android.databinding.DataBindingUtil.inflate(DataBindingUtil.java:116)
at android.databinding.DataBindingUtil.inflate(DataBindingUtil.java:88)
at com.algolia.instantsearch.ui.views.Hits$HitsAdapter.onCreateViewHolder(Hits.java:433)
at com.algolia.instantsearch.ui.views.Hits$HitsAdapter.onCreateViewHolder(Hits.java:398)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6367)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5555)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5440)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5436)
at android.support.v7.widget.linearlayoutmanager$LayoutState.next(linearlayoutmanager.java:2224)
at android.support.v7.widget.linearlayoutmanager.layoutChunk(linearlayoutmanager.java:1551)
at android.support.v7.widget.linearlayoutmanager.fill(linearlayoutmanager.java:1511)
at android.support.v7.widget.linearlayoutmanager.onLayoutChildren(linearlayoutmanager.java:595)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3583)
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3025)
at android.view.View.measure(View.java:19909)
at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:872)
at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:924)
at android.view.View.measure(View.java:19909)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:714)
at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:90)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1391)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:784)
at android.view.View.measure(View.java:19909)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:19909)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19909)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:19909)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19909)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:691)
at android.view.View.measure(View.java:19909)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2275)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1366)
08-31 14:32:00.511 22067-22067/com.algolia.app E/AndroidRuntime:     
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1619)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6343)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FramedisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6274)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

我不明白Kotlin项目中的相同代码如何触发Resources $NotFoundException.此外,资源ID似乎是奇数:0xffffffd6等于4294967254,它太大而不是有效整数.

什么可能导致这样的问题?我错过了在Kotlin应用程序中使用数据绑定的BindingAdapter的东西吗?

解决方法:

该问题是由底层库发送无效的View资源ID引起的.

关于记录学习在Android中使用kotlin.coroutinesandroid kotlin 教程的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android Kotlin Coroutines ktx扩展、Android Kotlin RXKotlin Room - 错误 Kotlin.unit、android – Kotlin coroutine吞下异常、android – 使用Kotlin进行数据绑定会导致资源$NotFoundException等相关知识的信息别忘了在本站进行查找喔。

本文标签: