1

背景

我下面的代码旨在防止每次用户选择图像时上传图像。本质上,我的目标是在开始上传之前创建“冷静”期,以节省用户的电池和数据。

问题

该代码运行良好,除非 Fragment 被销毁 OnComplete 在发出最后一个项目之前取消订阅订阅者,因此永远不会上传最新选择的图像。我想这是正确的行为,但我不知道如何解决它。

我的运气也很差debounce,不得不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);
        }
    }
}
4

1 回答 1

1

我假设正在发生的事情是碎片在 20 秒的弹跳之前被摧毁,对吧?

当调用 onCompleted 时,订阅者中的 onComplete 方法也会被调用,因此 onNext 不会被执行,因为订阅者没有调用它。

那这个呢?

@Override
public void onDestroy() {
    super.onDestroy();
    startPhotoUploadPublishSubject.onNext();
    startPhotoUploadPublishSubject.onCompleted();
}

它可能适用于您的情况。我认为对于这种情况,AsyncSubject 或 PublishSubject 之间没有区别。

希望能帮助到你

于 2015-11-05T22:51:59.130 回答