英文:
Android-RxJava: Update UI from background thread using observable
问题
package com.example.reactiveTest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class MainActivity extends AppCompatActivity {
private Button btnSend = null;
private TextView result = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.btnSend = findViewById(R.id.button_send);
this.result = findViewById(R.id.result);
}
public void onClickBtnSend(View view) {
createObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
// Disposable handling
}
@Override
public void onNext(String string) {
result.setText(string);
}
@Override
public void onError(Throwable e) {
// Handle error
}
@Override
public void onComplete() {
// Handle completion
}
});
}
private Observable<String> createObservable() {
return Observable.just("Just some String")
.map(s -> {
// Simulate server request and return response String
return response;
});
}
}
Please note that this code assumes you have added the necessary RxJava and RxAndroid dependencies to your project. The above code demonstrates how to create and subscribe to an Observable using RxJava for performing the network request and updating the UI on the main thread.
英文:
I just started building a simple Android app, in which I'd like to make a network request in a background thread and then update the main thread (UI thread) with the servers response. So far I used AsyncTasks
, but future implementations I'd like to use reactive Java (RxJava
). I have never done reactive calls before, so I'd like to have a simple but complete example (Observable and Observer creation and subscription) upon which it is possible to further build on.
I managed to include the RxJava dependency into the basic Android project and have written a very simple main activity using AsyncTasks for the network request. Now I tried to substitute the AsyncTask implementation with a reactive one, but got stuck in all the information regarding the Observable and Observer. I'm just not sure what exactly is necessary for a minimum but fully working example.
I'd really apprechiate a bit of help in transforming the main parts into an reactive implementation, since I don't know how to handle the generation of the Observable from the response string and subscribe an Observer.
Thanks.
package com.example.reactiveTest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button btnSend = null;
private TextView result = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.btnSend = findViewById(R.id.button_send);
this.result = findViewById(R.id.result);
}
public void onClickBtnSend(View view) {
new SomeTask().execute("Just some String");
}
class SomeTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
// server request returning response String
return response;
}
@Override
protected void onPostExecute(String string) {
// update UI with response String
result.setText(string);
}
}
}
答案1
得分: 4
使用AsyncTask,基本上你在工作线程上执行异步操作,然后在主线程上使用其结果。在Rx中,你会使用类似以下的方式:
Observable.fromCallable(asyncOperation)
.subscribeOn(backgroundThread)
.observeOn(mainThread)
.subscribe(result -> { /* 更新界面,例如 */ })
看起来你也对onNext
、onError
和onComplete
感兴趣。
- 每当可观察对象发出项目时,都会调用
onNext
。每次调用时,它都会接收一个项目,然后可以处理它。 - 当可观察对象由于任何原因遇到错误时,会调用
onError
。调用时,它会接收一个Throwable,表示错误的原因。在调用后,不会再调用onNext和onComplete。 - 在调用最后一个项目的onNext后调用
onComplete
。它不接收任何输入,例如,你可以在其中进行一些清理工作。
使用上述方法如下:
Observable.fromCallable(asyncOperation)
.subscribeOn(backgroundThread)
.observeOn(mainThread)
.subscribe(onNext, onError, onComplete)
【编辑】
如果你想使用Observable.create()
来创建自己的Observable,当然可以,它可以更精细地控制通过Observable发出的内容以及发出的时间。例如,如果你想处理一些特定的网络请求错误,并根据错误类型发出不同的Throwable
,就可以使用这种方式。
ObservableOnSubscribe asyncOperation = new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> emitter) {
try {
// 网络请求
// 一旦结果准备好,调用 emitter.onNext()。
// 完成后,通过调用 emitter.onComplete() 完成此Observable
} catch (Exception e) {
// 处理错误,并使用 emitter.onError() 发出错误
}
}
}
英文:
With AsyncTask, you're basically performing an asynchronous operation on a worker thread, then using its result on the main thread. In Rx you'd use something like the following:
Observable.fromCallable(asyncOperation)
.subscribeOn(backgroundThread)
.observeOn(mainThread)
.subscribe(result -> { /* update UI for instance */ })
It seems you're also interested in onNext
, onError
and onComplete
.
onNext
is called every time the observable emits an item. Each time it's called it receives an item, and can then process it.onError
is called when the observable has encountered an error for whatever reason. When it's called, it receives a Throwable, which represents the cause of the error. after it's called, onNext and onComplete are not called.onComplete
is called after onNext is called with the last item. It doesn't receive any input, you could do some clean up in it for example.
Using the above methods looks like this:
Observable.fromCallable(asyncOperation)
.subscribeOn(backgroundThread)
.observeOn(mainThread)
.subscribe(onNext, onError, onComplete)
[Edit]
If you'd like to create your Observable using Observable.create()
, you can definitely do that, it gives you finer control over what and when you emit through the Observable. You can do this for instance if you want to handle some specific errors that can result from your network request, and emit different Throwable
s depending on the error.
ObservableOnSubscribe asyncOperation = new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> emitter) {
try {
// network request
// Once result is ready, call emitter.onNext().
// When done, complete this Observable by calling emitter.onComplete()
} catch (Exception e) {
// handle error, and emit it using emitter.onError()
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论