【发布时间】:2016-02-06 16:07:04
【问题描述】:
背景
我下面的代码旨在防止每次用户选择图像时都上传图像。本质上,我的目标是在开始上传之前创建“冷静”期,以节省用户的电池和数据。
问题
代码运行良好,除非 Fragment 被销毁 OnComplete 在发出最后一项之前取消订阅订阅者,因此永远不会上传最新选择的图像。我想这是正确的行为,但我不知道如何解决它。
我对@987654321@ 的运气也很差,不得不改用TakeLast。结果是我想要的。
也许 AsyncSubject 会更好,但我不确定前进的方向。谢谢。
public class MyFragment extends Fragment {
private static final int DO_STUFF_REQUEST_CODE = 123173;
private static final int DEBOUNCE_TIME = 20;
private PublishSubject<Object> startPhotoUploadPublishSubject;
@Bind(R.id.photo)
ImageView photo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startPhotoUploadPublishSubject = PublishSubject.create();
startPhotoUploadPublishSubject
.observeOn(AndroidSchedulers.mainThread())
.takeLast(DEBOUNCE_TIME, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(new StartUploadPhotoIntentServiceSubscriber());
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
...
}
@Override
public void onDestroy() {
super.onDestroy();
startPhotoUploadPublishSubject.onCompleted();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == Crop.REQUEST_CROP) {
startPhotoUploadPublishSubject.onNext(null);
}
}
}
@OnClick(R.id.photo)
public void choosePhotoSelected() {
Intent chooserIntent = ...etc
startActivityForResult(chooserIntent, DO_STUFF_REQUEST_CODE);
}
private class StartUploadPhotoIntentServiceSubscriber extends Subscriber<Object> {
@Override
public void onCompleted() {
//do nothing
Toast.makeText(getActivity(), "ON COMPLETE", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
//we shouldnt have any errors
}
@Override
public void onNext(Object object) {
Toast.makeText(getActivity(), "ON NEXT", Toast.LENGTH_SHORT).show();
Intent uploadPhotoIntent = new Intent(
getActivity(), UploaderIntentService.class);
getActivity().startService(uploadPhotoIntent);
}
}
}
【问题讨论】:
-
AsyncSubject 而不是 PublishSubject 听起来更好,但我不太了解 Android 生命周期;由于您在 onDestroy 中调用 onCompleted(),我认为 getActivity() 不再起作用。
-
只是为了做到这一点:您是要上传多个项目 - 如果中间经过了足够的时间 - 还是只上传一个?
takeLast()让我假设您只想上传一项,但您的文字让我假设您想要上传多项。 -
我最初的计划是上传多个项目,因为用户可能会改变主意但不会离开活动,因此允许多个项目会更实用。我希望使用 debounce 而不是 last 但它不会触发 onNext
-
使用在所有内容上传之前一直运行的服务。您需要将其与 UI 生命周期分离。您无能为力。
-
我想我可以将项目添加到我的意图服务中,并检查是否已经存在具有相同签名的内容,或者相同请求的项目是否处于待处理状态,然后取消它们。谢谢大家的帮助!
标签: android rx-java onactivityresult debouncing