【问题标题】:Reactivex NetworkOnMainThreadException even when subcribed即使订阅了 Reactivex NetworkOnMainThreadException
【发布时间】:2018-11-30 15:13:23
【问题描述】:

我正在尝试构建一个使用 Reactivex 对 API 进行异步调用的 MVVM Kotlin 应用程序。

我见过很多有同样问题的线程,但在所有线程上,OP 都忘记在调用中输入subscribeOn,在我的代码中我这样做了,但仍然出现网络错误。我在调试器中查看了问题,但没有成功。

class NoteViewModel(apiKey : String) : ViewModel () { // , Observable {
private lateinit var noteAdapter : NoteAdapter

private val notesList = MutableLiveData <ArrayList<Note>>()
private var subscription : Disposable
private val noteCollector = NoteCollector()
private val isLoading = MutableLiveData<Boolean>()

init {
    subscription = noteCollector.getAll(apiKey)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSubscribe { onCollectNotesStart() }
            .doOnTerminate { onCollectNotesFinished() }
            .subscribe(
                    { result -> onCollectNotesSuccess(result) },
                    { error -> onCollectNotesError(error) }
            )
}
...
}

如果您需要更多信息,请告诉我,我会提供。

编辑:添加堆栈跟踪

E/AndroidRuntime: FATAL EXCEPTION: main
Process: jari.student.hogent.cominghome, PID: 2532
java.lang.RuntimeException: Unable to start activity ComponentInfo{jari.student.hogent.cominghome/jari.student.hogent.cominghome.Activities.MainActivity}: android.os.NetworkOnMainThreadException
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2955)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6938)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
 Caused by: android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1448)
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:102)
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90)
    at java.net.InetAddress.getAllByName(InetAddress.java:787)
    at com.android.okhttp.Dns$1.lookup(Dns.java:39)
    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:200)
    at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:148)
    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:90)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:190)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:142)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:104)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:410)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:343)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:489)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:262)
    at com.github.kittinunf.fuel.toolbox.HttpClient.setBodyIfDoOutput(HttpClient.kt:91)
    at com.github.kittinunf.fuel.toolbox.HttpClient.executeRequest(HttpClient.kt:39)
    at com.github.kittinunf.fuel.core.requests.TaskRequest.call(TaskRequest.kt:14)
    at com.github.kittinunf.fuel.core.DeserializableKt$response$result$1.invoke(Deserializable.kt:81)
    at com.github.kittinunf.fuel.core.DeserializableKt$response$result$1.invoke(Unknown Source:0)
    at com.github.kittinunf.result.Result$Companion.of(Result.kt:116)
    at com.github.kittinunf.fuel.core.DeserializableKt.response(Deserializable.kt:81)
    at com.github.kittinunf.fuel.core.Request.responseObject(Request.kt:344)
    at jari.student.hogent.cominghome.Models.NoteCollector.getAll(NoteCollector.kt:22)
    at jari.student.hogent.cominghome.ViewModels.NoteViewModel.<init>(NoteViewModel.kt:22)
    at jari.student.hogent.cominghome.ViewModels.CustomViewModelFactory.create(CustomViewModelFactory.kt:11)
    at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134)
    at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102)
    at jari.student.hogent.cominghome.Fragments.NoteFragment.onCreateView(NoteFragment.kt:27)
    at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
    at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
    at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
    at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
    at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
    at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
    at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:620)
    at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1340)
    at android.app.Activity.performStart(Activity.java:7200)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2918)
        ... 9 more

编辑 2:添加 getAll 方法

override fun getAll(ApiKey: String): Observable<ArrayList<Note>> {
    val bodyJson: JSONObject = JSONObject()
            .put("apiKey", ApiKey)

    val notesList: ArrayList<Note> = ArrayList()

    val (_, _, result) = path.httpPost()
            .header(mapOf("Content-Type" to "application/json"))
            .body(bodyJson.toString())
            .responseObject(Note.Deserializer())
    val (notes, err) = result
    if (err != null){
        throw err.exception
    }
    notes?.forEach { note ->
        notesList.add(note)
    }

    return Observable.fromArray(notesList)
}

【问题讨论】:

  • onCollectLocationsStart()onCollectLocationsFinished() 做什么?
  • @AndreyIlyunin isLoading.value = false 或 true of course,取决于方法
  • 也许有人开了一个愤怒的玩笑,做了RxJavaPlugins.setIoScheduler(scheduler -&gt; AndroidSchedulers.mainThead())之类的东西?
  • 另外,如果你能放一个堆栈跟踪——那就太好了
  • @AndreyIlyunin 也尝试过Schedulers.newThread() 所以不要这么认为。我将使用堆栈跟踪进行编辑

标签: mvvm kotlin rx-java2 reactivex


【解决方案1】:

请将您的 getAll 实现更改为:

override fun getAll(ApiKey: String): Observable<ArrayList<Note>> 
    = Observable.create { emitter -> 
        val bodyJson: JSONObject = JSONObject()
                .put("apiKey", ApiKey)

        val notesList: ArrayList<Note> = ArrayList()

        val (_, _, result) = path.httpPost()
                .header(mapOf("Content-Type" to "application/json"))
                .body(bodyJson.toString())
                .responseObject(Note.Deserializer())
        val (notes, err) = result
        if (err != null) {
            throw err.exception
        }
        notes?.forEach { note ->
            notesList.add(note)
        }
        emitter.onNext(notesList)
    }

【讨论】:

  • 我在emitter.onNext(note) 上遇到类型不匹配,它需要一个数组列表而不是一个注释。
猜你喜欢
  • 1970-01-01
  • 2021-03-25
  • 2016-12-14
  • 2016-12-11
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多