Skip to content
This repository has been archived by the owner on Mar 16, 2021. It is now read-only.

RxJava2 support #54

Merged
merged 7 commits into from
Jan 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rx2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
55 changes: 55 additions & 0 deletions rx2/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.novoda:bintray-release:$bintrayVersion"
}
}

apply plugin: 'com.android.library'
apply plugin: 'bintray-release'
apply plugin: 'jacoco-android'

android {
compileSdkVersion COMPILE_SDK_VERSION
buildToolsVersion BUILD_TOOLS_VERSION

defaultConfig {
minSdkVersion MIN_SDK_VERSION
targetSdkVersion TARGET_SDK_VERSION
versionCode VERSION_CODE
versionName VERSION_NAME
}
buildTypes {
release {
minifyEnabled false
}
debug {
// output coverage with ./gradlew clean build createDebugCoverageReport
testCoverageEnabled true
}
}
lintOptions {
abortOnError false
}
}

dependencies {
compile project(':thirtyinch')
compile 'io.reactivex.rxjava2:rxjava:2.0.3'
provided "com.android.support:support-annotations:$supportLibraryVersion"

testCompile "junit:junit:$junitVersion"
testCompile "org.mockito:mockito-core:$mockitoVersion"
}

publish {
userOrg = 'passsy'
groupId = 'net.grandcentrix.thirtyinch'
artifactId = 'thirtyinch-rx'
uploadName = 'ThirtyInch'
publishVersion = VERSION_NAME
//description = ''
website = 'https://github.com/grandcentrix/ThirtyInch'
}
5 changes: 5 additions & 0 deletions rx2/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<manifest package="net.grandcentrix.thirtyinch.rx2">

<application />

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (C) 2016 grandcentrix GmbH
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.grandcentrix.thirtyinch.rx2;

import net.grandcentrix.thirtyinch.TiLifecycleObserver;
import net.grandcentrix.thirtyinch.TiPresenter;
import net.grandcentrix.thirtyinch.TiView;

import android.support.annotation.NonNull;

import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;

public class RxTiPresenterDisposableHandler {

private CompositeDisposable mPresenterDisposables = new CompositeDisposable();

private CompositeDisposable mUiDisposables;

public RxTiPresenterDisposableHandler(final TiPresenter presenter) {
presenter.addLifecycleObserver(new TiLifecycleObserver() {
@Override
public void onChange(final TiPresenter.State state,
final boolean beforeLifecycleEvent) {
if (state == TiPresenter.State.VIEW_DETACHED && beforeLifecycleEvent) {
// dispose all UI disposable created in onAttachView(TiView) and added
// via manageViewDisposable(Disposable...)
if (mUiDisposables != null) {
mUiDisposables.dispose();
mUiDisposables = null;
}
}

if (state == TiPresenter.State.VIEW_ATTACHED && beforeLifecycleEvent) {
mUiDisposables = new CompositeDisposable();
}

if (state == TiPresenter.State.DESTROYED && beforeLifecycleEvent) {
mPresenterDisposables.dispose();
mPresenterDisposables = null;
}
}
});

}

/**
* Add your disposables here and they will automatically disposed when
* {@link TiPresenter#destroy()} gets called
*
* @throws IllegalStateException when the presenter has reached {@link net.grandcentrix.thirtyinch.TiPresenter.State#DESTROYED}
*/
public void manageDisposable(@NonNull final Disposable... disposables) {
if (mPresenterDisposables == null) {
throw new IllegalStateException("disposable handling doesn't work"
+ " when the presenter has reached the DESTROYED state");
}

addDisposables(mPresenterDisposables, disposables);
}

/**
* Add your disposables for View events to this method to get them automatically cleaned up
* in {@link TiPresenter#detachView()}. typically call this in {@link
* TiPresenter#attachView(TiView)} where you dispose to the UI events.
*
* @throws IllegalStateException when no view is attached
*/
public void manageViewDisposable(@NonNull final Disposable... disposables) {
if (mUiDisposables == null) {
throw new IllegalStateException("view disposable can't be handled"
+ " when there is no view");
}

addDisposables(mUiDisposables, disposables);
}

/**
* Adds all disposables to the given compositeDisposable if not already disposed
*/
private static void addDisposables(final CompositeDisposable compositeDisposable,
final Disposable... disposables) {
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < disposables.length; i++) {
final Disposable disposable = disposables[i];
if (disposable.isDisposed()) {
continue;
}

compositeDisposable.add(disposable);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2016 grandcentrix GmbH
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.grandcentrix.thirtyinch.rx2;

import net.grandcentrix.thirtyinch.Removable;
import net.grandcentrix.thirtyinch.TiLifecycleObserver;
import net.grandcentrix.thirtyinch.TiPresenter;
import net.grandcentrix.thirtyinch.TiView;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.disposables.Disposable;

public class RxTiPresenterUtils {

/**
* Observable of the view state. The View is ready to receive calls after calling {@link
* TiPresenter#attachView(TiView)} and before calling {@link TiPresenter#detachView()}.
*/
public static Observable<Boolean> isViewReady(final TiPresenter presenter) {
return Observable.create(
new ObservableOnSubscribe<Boolean>() {
@Override
public void subscribe(final ObservableEmitter<Boolean> emitter)
throws Exception {
if (!emitter.isDisposed()) {
emitter.onNext(presenter.getState()
== TiPresenter.State.VIEW_ATTACHED);
}

final Removable removable = presenter
.addLifecycleObserver(new TiLifecycleObserver() {
@Override
public void onChange(final TiPresenter.State state,
final boolean beforeLifecycleEvent) {
if (!emitter.isDisposed()) {
emitter.onNext(state ==
TiPresenter.State.VIEW_ATTACHED);
}
}
});

emitter.setDisposable(new Disposable() {
@Override
public void dispose() {
removable.remove();
}

@Override
public boolean isDisposed() {
return removable.isRemoved();
}
});
}
})
.distinctUntilChanged();
}

}
Loading