สมัครสมาชิกและยกเลิกการสมัครในแต่ละรายการที่ปล่อยออกมา

ฉันใช้ lib reactive-location

กรณีการใช้งานของฉันคือฉันมีวัตถุมากมายที่ปล่อยออกมาจากการสังเกตได้ รายการเหล่านี้สามารถส่งออกได้ทุกสองสามชั่วโมง ทันทีที่มีการปล่อยรายการฉันต้องการรับตำแหน่งและใช้ zipWith (เท่าที่ฉันเข้าใจ) จะปล่อยวัตถุที่มีตำแหน่งนั้น

ปัญหาคือ เนื่องจากวัตถุจะถูกปล่อยออกมาทุกๆ สองสามชั่วโมงเท่านั้น ฉันจึงไม่สามารถรักษาตำแหน่งที่ร้อนจนสังเกตได้เนื่องจากจะทำให้แบตเตอรี่หมด

ดังนั้นฉันต้องการสิ่งต่อไปนี้: เมื่อวัตถุถูกส่งเข้าสู่สตรีม ให้สมัครรับตำแหน่งที่สังเกตได้เมื่อได้รับตำแหน่งแล้ว ยกเลิกการสมัครรับตำแหน่งที่สังเกตได้ จะต้องดำเนินการอย่างต่อเนื่อง

เท่าที่ฉันเข้าใจหม้อแปลงนี้จะดูแลการยกเลิกการสมัคร

public <T> Observable.Transformer<T, T> takeNextAndUnsubscribe() {
    return new Observable.Transformer<T, T>() {

        @Override
        public Observable<T> call(Observable<T> tObservable) {
            final BehaviorSubject subject = BehaviorSubject.create();
            Observable source = tObservable.doOnNext(new Action1<T>() {
                @Override
                public void call(T t) {
                    subject.onNext(t);
                }
            });
            return Observable
                    .merge(source.takeUntil(subject), subject)
                    .take(1);
        }

    };
}

แต่ฉันจะสมัครสมาชิกอีกครั้งได้อย่างไรเมื่อมีออบเจ็กต์ใหม่ถูกส่งลงมาในสตรีม


person jiduvah    schedule 22.10.2015    source แหล่งที่มา


คำตอบ (1)


ดูเหมือนว่าสิ่งที่คุณต้องการคือการรวมรายการต้นฉบับเข้ากับตำแหน่งปัจจุบันเมื่อมีการปล่อยออกมา ไม่จำเป็นต้องมีอะไรแฟนซีที่นี่ เพียงใช้ flatMap() กับแต่ละรายการต้นทางเพื่อรวมเข้ากับตำแหน่ง

source.flatMap(item ->
        locationProvider
                .getLastKnownLocation()
                .map(location -> new ItemWithLocation<>(item, location))
);

class ItemWithLocation<T> {
    private final T item;
    private final Location location;

    public ItemWithLocation(T item, Location location) {
        this.item = item;
        this.location = location;
    }

    public T getItem() {
        return item;
    }

    public Location getLocation() {
        return location;
    }
}

แก้ไข: อัปเดตด้วยตัวอย่างที่สอง รายการต่อไปนี้จะสมัครรับการอัปเดตตำแหน่งจนกว่าจะถึงความแม่นยำที่กำหนด จากนั้นจึงรวมเข้ากับรายการแหล่งที่มาของคุณ สิ่งสำคัญที่นี่คือการใช้ first() การใช้มันจะยกเลิกการสมัครจากผู้ให้บริการตำแหน่งเมื่อใดก็ตามที่คุณได้รับสถานที่ที่ตรงกับความต้องการของคุณ

LocationRequest request = 
        LocationRequest
            .create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(100);

source.flatMap(item ->
        locationProvider
                .getUpdatedLocation(request)
                .first(location -> location.getAccuracy() < 5.0f)
                .map(location -> new ItemWithLocation<>(item, location))
);
person kjones    schedule 23.10.2015
comment
ปัญหาคือฉันต้องการที่ตั้งใหม่ ไม่ใช่ที่ทราบล่าสุด - person jiduvah; 23.10.2015
comment
คุณใช้ API ใดจากตำแหน่งปฏิกิริยา มันไม่ชัดเจน ดังนั้นฉันจึงใช้ getLastKnownLocation() ในตัวอย่างของฉัน ฉันได้อัปเดตคำตอบด้วยตัวอย่างที่สองที่แสดงวิธีจัดการการยกเลิกการสมัครจากตำแหน่งที่สังเกตได้ไม่สิ้นสุด - person kjones; 23.10.2015