Reactivex NetworkOnMainThreadException即使被订阅

时间:2018-11-30 15:13:24

标签: mvvm kotlin rx-java2 reactivex

我正在尝试构建一个使用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)
}

1 个答案:

答案 0 :(得分: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)
    }