All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.wandersnail.common.http.upload.UploadObserver Maven / Gradle / Ivy

package cn.wandersnail.common.http.upload;

import java.util.HashMap;
import java.util.Map;

import cn.wandersnail.common.http.TaskInfo;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Response;

/**
 * date: 2019/8/23 18:26
 * author: zengfansheng
 */
class UploadObserver implements Observer>, Disposable, UploadProgressListener {
    private static final int UPDATE_LIMIT_DURATION = 500;//限制进度更新频率,毫秒
    private final UploadInfo info;
    private final UploadListener listener;
    private Disposable disposable;
    private long lastUpdateTime;//上次进度更新时间
    private Map contentLengthMap = new HashMap<>();

    UploadObserver(UploadInfo info, UploadListener listener) {
        this.info = info;
        this.listener = listener;
    }

    @Override
    public void onProgress(String name, long progress, long max) {
        Schedulers.io().scheduleDirect(() -> {
            long completionLength = progress;
            Long contentLen = contentLengthMap.get(name);
            if (contentLen != null && contentLen > max) {
                completionLength += contentLen - max;
            } else {
                contentLengthMap.put(name, max);
                contentLen = max;
            }
            if (System.currentTimeMillis() - lastUpdateTime >= UPDATE_LIMIT_DURATION && (info.state == TaskInfo.State.IDLE ||
                    info.state == TaskInfo.State.START || info.state == TaskInfo.State.ONGOING)) {
                if (info.state != TaskInfo.State.ONGOING) {
                    info.state = TaskInfo.State.ONGOING;
                    if (listener != null) {
                        listener.onStateChange(info.state, null);
                    }
                }
                if (listener != null) {
                    listener.onProgress(name, completionLength, contentLen);
                }
                lastUpdateTime = System.currentTimeMillis();
            }
        });
    }

    @Override
    public void onSubscribe(Disposable d) {
        disposable = d;
        info.state = TaskInfo.State.START;
        if (listener != null) {
            listener.onStateChange(info.state, null);
        }
    }

    @Override
    public void onNext(Response response) {
        if (info.converter != null) {
            try {
                T convertedBody = info.converter.convert(response.body());
                if (listener != null) {
                    listener.onResponseBodyParse(response.raw(), convertedBody);
                }
            } catch (Exception e) {
                onError(e);
            }
        } else if (listener != null) {
            listener.onResponseBodyParse(response.raw(), null);
        }
    }

    @Override
    public void onError(Throwable e) {
        disposable = null;
        info.state = TaskInfo.State.ERROR;
        if (listener != null) {
            listener.onStateChange(info.state, e);
        }
    }

    @Override
    public void onComplete() {
        disposable = null;
        if (listener != null) {
            for (Map.Entry entry : contentLengthMap.entrySet()) {
                listener.onProgress(entry.getKey(), entry.getValue(), entry.getValue());
            }
        }
        info.state = TaskInfo.State.COMPLETED;
        if (listener != null) {
            listener.onStateChange(info.state, null);
        }
    }

    @Override
    public void dispose() {
        Schedulers.io().scheduleDirect(() -> {
            if (!isDisposed()) {
                disposable.dispose();
            }
            if (info.state == TaskInfo.State.ONGOING || info.state == TaskInfo.State.START) {
                info.state = TaskInfo.State.CANCEL;
                if (listener != null) {
                    listener.onStateChange(info.state, null);
                }
            }
        });
    }

    @Override
    public boolean isDisposed() {
        return disposable == null || disposable.isDisposed();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy