Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用改型/Rxjava进行数据绑定/实时数据处理配置更改_Java_Android_Retrofit_Rx Java2_Mutablelivedata - Fatal编程技术网

使用改型/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);
        });
    }
}