使用改型/Rxjava进行数据绑定/实时数据处理配置更改
请看下面的代码: 主要活动:使用改型/Rxjava进行数据绑定/实时数据处理配置更改,java,android,retrofit,rx-java2,mutablelivedata,Java,Android,Retrofit,Rx Java2,Mutablelivedata,请看下面的代码: 主要活动: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MutableLiveData<User> mutableUser = new MutableLiveData<>(); mutableUser.setValue(new U
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
MutableLiveData<User> mutableUser = new MutableLiveData<>();
mutableUser.setValue(new User("John","Gordon","Homeless"));
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
activityMainBinding.setHandler(new MainActivityHandler());
activityMainBinding.setLifecycleOwner(this);
activityMainBinding.setUser(mutableUser);
setSupportActionBar(activityMainBinding.toolbar);
}
这很好,配置更改被跟踪并填充到gui中(例如,当我在“名称”字段中键入某个内容时,当屏幕旋转时,值仍然存在)
接下来,我想从rest webservice-Reformation/RxJava实现刷新用户详细信息,并想在数据加载过程中显示忙碌指示器,例如,在onCreate
方法中:
showBusyIndicator();
testService.getUserDetails(headers)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(user ->
{
hideBusyIndicator();
activityMainBinding.getUser().setValue(user);
}, throwable ->
{
Log.d(TAG, "ERROR loading user");
hideBusyIndicator();
});
现在我不知道如何正确处理配置更改-当显示忙碌指示器时,应该在屏幕旋转更改后重新创建它。由于MutableLiveData
能够很好地处理配置更改,因此我无法找到任何解决方案(除了“经典”方法)来解决我在这种情况下加载指示器和处理结果的问题
你能给我指一下正确的方向吗
[编辑]
getUserDetails声明:
@NonNull
@GET("/user")
Observable<User> getUserDetails(@HeaderMap Map<String, String> headers);
@NonNull
@获取(“/user”)
可观察的getUserDetails(@HeaderMap-headers);
@用户8035311
我修改了github示例,在单击按钮时触发模拟数据加载,这种方式(按钮已添加到布局中):
@覆盖
创建时受保护的void(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.progressDialog=新建progressDialog(this);
这个.progressDialog.setMessage(“加载…”);
final ActivityMainBinding mainBinding=DataBindingUtil.setContentView(this,R.layout.activity_main);
mainBinding.setLifecycleOwner(此);
mainBinding.button2.setOnClickListener(视图->
{
RxViewModel.RxViewModelFactory=新的RxViewModel.RxViewModelFactory();
最终RxViewModel模型=ViewModelProviders.of(MainActivity.this,factory).get(RxViewModel.class);
LiveData LiveData=model.getLiveData();
progressDialog.show();
liveData.observe(MainActivity.this,s->
{
progressDialog.disclose();
mainBinding.setUser;
});
});
}
但这是行不通的。任务在屏幕旋转时中断,但以下情况除外:
06-27 09:05:18.737
11829-11829/app.rxrotation.com.architecture组件rxrotation
E/WindowManager:android.view.WindowManager:Activity
app.rxrotation.com.architecturecomponentsrxrotation.main活动已停止
漏窗DecorView@5b16e38[]最初添加到此处的
在android.view.ViewRootImpl。(ViewRootImpl.java:485)
在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:346)
在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
在android.app.Dialog.show上(Dialog.java:330)
在app.rxrotation.com.architecturecomponentsrxrotation.MainActivity.lambda$onCreate$1$MainActivity(MainActivity.java:35)
在app.rxrotation.com.architecturecomponentsrxrotation.MainActivity$$Lambda$0.onClick(未知
资料来源:4)
在android.view.view.performClick上(view.java:6294)
在android.view.view$PerformClick.run(view.java:24770)
位于android.os.Handler.handleCallback(Handler.java:790)
位于android.os.Handler.dispatchMessage(Handler.java:99)
位于android.os.Looper.loop(Looper.java:164)
位于android.app.ActivityThread.main(ActivityThread.java:6494)
位于java.lang.reflect.Method.invoke(本机方法)
位于com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
第二次单击按钮后,数据加载甚至没有执行。您可以使用
ViewModel
和LiveData
在配置更改后保留异步任务。因此,您的LiveData
可以如下所示:
public class UserLiveData extends LiveData<User> {
public UserLiveData() {
setValue(new User());
}
public UserLiveData(Headers headers) {
Observable<User> observable = Observable.defer(new Callable<ObservableSource<? extends User>>() {
@Override
public ObservableSource<? extends User> call() throws Exception {
User user = testService.getUserDetails(headers);
return Observable.just(user);
}
});
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DefaultObserver<String>() {
@Override
public void onNext(User value) {
setValue(value);
}
@Override
public void onError(Throwable e) {
throw new RuntimeException(e);
}
@Override
public void onComplete() {
}
});
}
}
然后您的main活动可以如下所示:
public class UserDetailsViewModel extends ViewModel {
private LiveData<User> userLiveData;
public UserDetailsViewModel() {
userLiveData = new UserLiveData();
}
public void observeLiveDate(LifecycleOwner owner,
Observer<User> observer) {
userLiveData.observe(owner, observer);
}
public void loadLiveData(Headers headers) {
userLiveData = new UserLiveData(someArgs);
}
}
public class MainActivity extends AppCompatActivity {
private ProgressDialog progressDialog;
private UserViewModel viewModel;
private ActivityMainBinding mainBinding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.progressDialog = new ProgressDialog(this);
this.progressDialog.setMessage("Loading...");
mainBinding = DataBindingUtil.setContentView(this,
R.layout.activity_main);
mainBinding.setLifecycleOwner(this);
viewModel = ViewModelProviders.of(this).get(UserViewModel.class);
observeLiveData();
mainBinding.button2.setOnClickListener(v -> {
viewModel.initLiveData(<your headers>);
observeLiveData();
});
}
private void observeLiveData() {
progressDialog.show();
progressDialog.setCanceledOnTouchOutside(false);
viewModel.observeRxLiveDate(this, user -> {
progressDialog.dismiss();
mainBinding.setUser(user);
});
}
}
public类MainActivity扩展了AppCompatActivity{
私有进程对话;
私有用户视图模型;
私人活动主绑定主绑定;
@凌驾
创建时受保护的void(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.progressDialog=新建progressDialog(this);
这个.progressDialog.setMessage(“加载…”);
mainBinding=DataBindingUtil.setContentView(此,
R.布局、活动(主要部分);
mainBinding.setLifecycleOwner(此);
viewModel=ViewModelProviders.of(this.get)(UserViewModel.class);
observevidata();
mainBinding.button2.setOnClickListener(v->{
initLiveData();
observevidata();
});
}
私有void observevidata(){
progressDialog.show();
progressDialog.setCanceledOnTouchOutside(false);
viewModel.observeRxLiveDate(此,用户->{
progressDialog.disclose();
mainBinding.setUser(用户);
});
}
}
我创建了一个非常简单的示例为什么不使用CompositeDisposable,方法是在onResume中订阅一个任务并在onPause中清除它?您能给我看一些示例吗?我修改了示例代码(仅从rest服务加载的单个用户),以简化它getUserDetails
是改型接口方法,没有什么特别的方法,我将测试并最终接受您的答案。抱歉,尚未尝试,很遗憾,我正忙于其他项目:(在我的实际项目中,我有20或30个Web服务调用,使用这种方法,我需要为每个调用创建2个类。有没有办法避免像这样的样板代码?还有,任务执行不会在配置更改时中断?我假设我需要在一旦更改
中添加繁忙指示器隐藏,但在配置更改后如何重新创建它?@user1209216这是一个更难的问题:)。我将尝试给出一个例子。是否可以在y中使用RxJava集成的改进
public class UserDetailsViewModel extends ViewModel {
private LiveData<User> userLiveData;
public UserDetailsViewModel() {
userLiveData = new UserLiveData();
}
public void observeLiveDate(LifecycleOwner owner,
Observer<User> observer) {
userLiveData.observe(owner, observer);
}
public void loadLiveData(Headers headers) {
userLiveData = new UserLiveData(someArgs);
}
}
public class MainActivity extends AppCompatActivity {
private ProgressDialog progressDialog;
private UserViewModel viewModel;
private ActivityMainBinding mainBinding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.progressDialog = new ProgressDialog(this);
this.progressDialog.setMessage("Loading...");
mainBinding = DataBindingUtil.setContentView(this,
R.layout.activity_main);
mainBinding.setLifecycleOwner(this);
viewModel = ViewModelProviders.of(this).get(UserViewModel.class);
observeLiveData();
mainBinding.button2.setOnClickListener(v -> {
viewModel.initLiveData(<your headers>);
observeLiveData();
});
}
private void observeLiveData() {
progressDialog.show();
progressDialog.setCanceledOnTouchOutside(false);
viewModel.observeRxLiveDate(this, user -> {
progressDialog.dismiss();
mainBinding.setUser(user);
});
}
}