gpt4 book ai didi

android - 单一导致主线程上的网络或错误线程异常的查看根

转载 作者:行者123 更新时间:2023-11-29 00:53:24 25 4
gpt4 key购买 nike

使用简单的 RxKotlin Single,我收到了 android.view.ViewRootImpl$CalledFromWrongThreadException 异常,或者通过添加 .observeOn(AndroidSchedulers.mainThread()) ,我遇到了 NetworkOnMainThread 异常。

fun loadStaffCalendar() {
var calendarParser = CalendarParser()
calendarParser.getSingleBearCal()
.subscribeOn(Schedulers.io())
.subscribeBy(
onError ={error("Error loading calendar\n${it.message}")},
onSuccess = { responseBody ->
println("ResponseBody retrieved")
var staffList = calendarParser.parseStringIntoSchedule(responseBody.string())
view.loadToAdapter(staffList)
println(staffList)

}

)

我可以让 staffList 在控制台中打印,但是一旦我尝试将它加载到 View 的适配器中,它就会崩溃并出现 CalledFromWrongThread 异常。

所以这是我添加 .observeOn(AndroidSchedulers.mainThread()) 时的崩溃:

Process: com.offbroadwaystl.archdemo, PID: 21809
io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | android.os.NetworkOnMainThreadException
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:126)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at com.android.org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:415)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:527)
at okio.InputStreamSource.read(Okio.kt:102)

任何地方都不会进行额外的网络调用。剩下的是:

class CalendarParser : AnkoLogger {
fun getSingleBearCal(): Single<ResponseBody> {
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("https://www.brownbearsw.com/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
val bearApi: BearApi = retrofit.create(BearApi::class.java)

return bearApi.file
}

fun parseStringIntoSchedule(wholeSchedule: String): ArrayList<StaffModel> {
var dateMap: HashMap<LocalDate, String> = HashMap()
var endDelim = "END:VEVENT"
var events: List<String> = wholeSchedule.split(endDelim)
var parsedStaffCal: ArrayList<StaffModel> = ArrayList()
var today = LocalDate.now()
// :: Pull event date from event data, pull staff list from "SUMMARY" line :: //
events.forEach {
var tempString = (it.substringAfterLast("DATE:", "FAIL").take(8))
var dateTime: LocalDate = eightIntoDateTime(tempString)

var summary: String = it.substringAfter("SUMMARY:", "FAIL")
.let { it.substringBefore("UID").replace("\\n", "\n") }
dateMap.put(dateTime, summary)
}

// ::Filter out all days before today:: //
dateMap.forEach {
if (!it.key.isBefore(today)) {
val staffModel = StaffModel(it.key, it.value)
parsedStaffCal.add(staffModel)
}
}
//:: Sort chronologically :://
parsedStaffCal.sortBy { it.localDate }

return parsedStaffCal
}

fun eightIntoDateTime(s: String): LocalDate {
return if (s.length == 8 && s.isDigitsOnly()) { // <-=-=-=-=-=- avoid potential formatting exceptions
val dateString = ("${s.subSequence(0, 4)}-${s.subSequence(4, 6)}-${s.subSequence(6, 8)}")
LocalDate.parse(dateString)
} else LocalDate.parse("1999-12-31")
}

改造 API:

package com.offbroadwaystl.archdemo.schedule;

import io.reactivex.Single;
import okhttp3.ResponseBody;
import retrofit2.http.GET;
import retrofit2.http.Streaming;

public interface BearApi {
@Streaming
@GET("url.goes.here.ics")
Single<ResponseBody> getFile();
}

最佳答案

subscribeOn 告诉可观察者在哪里执行工作,然后 observeOn 就是这个工作的结果将被返回的地方。在您的情况下,您需要:

calendarParser.getSingleBearCal()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).
......

关于android - 单一导致主线程上的网络或错误线程异常的查看根,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57342833/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com