我是RxJava
的新手,我需要将它集成到现有的项目中。我需要重构现有代码,为网络添加Observables
(套接字IO)。
目前,当发出网络请求(客户端->服务器)时,会向HashMap
添加一个回调(接口),一旦请求完成,它会将数据传递回调用者:
// Singleton
public class API {
public void checkTicket(String ticketId, final String networkRequestId, Callback callback) {
// Add the callback to the hashmap
registerCallback(networkRequestId, callback);
JSONObject json = RequestFactory.createTicketCheckerRequest(ticketId);
// Make the network request
getSocket().checkTicket(json, new Callback() {
@Override
public void onRequestDone(Response response) {
// Retrieve the callback
callback = getCallback(networkRequestId);
// Don't keep reference, remove from hashmap
unsubscribeCallback(networkRequestId);
// Check if it's unsuccessful and build the corresponding error response
if (!response.isSuccess()) {
// build custom error response
response = ResponseFactory.buildError(response);
}
// Deliver response from server
callback.onRequestDone(response);
}
});
}
}
可以从Activities
和Fragments
调用它
private void checkTicket() {
String ticketId = editText.getText().toString();
API.getInstance().checkTicket(ticketId, REQUEST_ID_CHECK_TICKET, new Callback() {
@Override
protected void onRequestDone(Response response) {
textView.setText(response.getData());
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
// Removes callback from HashMap in case of the UI is destroyed before the arrives
API.getInstance().unsubscribe(REQUEST_ID_CHECK_TICKET);
}
上面的代码可以工作,但它与UI的生命周期非常紧密,有时会导致内存泄漏,因为onDestroy()
不会被调用(如果你在活动之间导航,安卓操作系统会从堆栈中删除“暂停的”活动),或者因为匿名内部类(回调)持有对UI的引用,并且从现在开始我需要支持方向更改。
这是我使用RxJava
实现的代码
接口
public Observable<Response> checkTicket(String ticketId) {
return Observable.create(subscriber -> {
JSONObject json = RequestFactory.createTicketCheckerRequest(ticketId);
// Make the network request
getSocket().checkTicket(json, new Callback() {
@Override
public void onRequestDone(Response response) {
subscriber.onNext(response);
subscriber.onComplete();
}
});
});
}
下面是从UI中调用它的方式:
private CompositeDisposable mDisposables = new CompositeDisposable();
private void checkTicket() {
//////
Disposable disposable = API.getInstance().checkTicket(ticketId)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(result -> {
textView.setText(result.getData());
});
mDisposables.add(disposable);
}
@Override
public void onStop() {
super.onStop();
if (!mDisposables.isDisposed()) {
mDisposables.dispose();
}
}
上面的RxJava
正在工作,但是,如果方向发生更改,则不会返回数据,因为Observer
已取消订阅。
另一种选择是EventBus,但这只是B计划。EventBus完全符合我的要求,订阅并等待数据更改,但我想驱逐样板。
我读过其他使用Fragment
的setRetainInstance(true)
的文章,但是如果我需要在Activity
中使用它呢?如果我不想保留Fragment
的状态呢?人们建议使用MVVM
或MVP
架构,但我没有时间重构整个项目。
发布于 2018-07-05 01:05:55
我建议您迁移到MVVM。使用您提供的代码,这并不难。下面是一个样例代码,展示了它的外观
Your ModelView
public class MyViewModel extends ViewModel {
private CompositeDisposable mDisposables = new CompositeDisposable();
private MutableLiveData<Response> response;
public LiveData<Response> getResponse() {
if (response == null) {
response = new MutableLiveData<Response>();
loadData();
}
return response;
}
private void loadData() {
Disposable disposable = API.getInstance().checkTicket(ticketId)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(result -> {
response.postValue(result.getData());
});
mDisposables.add(disposable);
}
void onCleared()
{
super.onCleared();
mDisposables.clear(); //no more leaks. It takes care of lifecycle for you
}
}
Your Activity
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getResponse().observe(this, response -> {
// update UI
textView.setText(response); //response = Response object from Live data
});
}
}
发布于 2018-07-04 18:11:01
如果您不想处理配置更改,而希望缓存来自可观察对象的数据,则可以使用BehaviorSubjects和一个热可观察对象。这将允许您获取observable发布的最新项。
除此之外,我建议您使用架构组件中的ViewModel
。它将允许您创建绑定到活动但不受生命周期影响的组件(显然,终止除外)。令人惊讶的是,使用setRetainInstance(true)
将ViewModelProviders实现为片段。你不必完全重构整个应用程序。只需移动您想要在配置更改期间保留的那些。
https://stackoverflow.com/questions/51169122
复制相似问题