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