- General
- Mastering Observable - http://docs.couchbase.com/developer/java-2.0/observables.html
- Android
- Grokking RxJava, Part 1-4 - http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
- Loading data from multiple sources with RxJava - http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/
- Don't break the chain: use RxJava's compose() operator - http://blog.danlew.net/2015/03/02/dont-break-the-chain/
- Pro RxJava
- Hot and Cold Observable - http://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx
- To use subject or not to use subject - http://davesexton.com/blog/post/To-Use-Subject-Or-Not-To-Use-Subject.aspx
- RxJava Threading Examples - http://www.grahamlea.com/2014/07/rxjava-threading-examples/
package jp.wasabeef.sample; | |
import android.content.Context; | |
import android.graphics.SurfaceTexture; | |
import android.opengl.GLDebugHelper; | |
import android.util.AttributeSet; | |
import android.util.Log; | |
import android.view.TextureView; | |
import android.view.View; | |
import java.io.Writer; |
// Dagger 1 example | |
@Module( | |
complete = false, | |
library = true | |
) | |
public final class ApiModule { | |
@Provides | |
@Singleton | |
Retrofit provideRetrofit(Gson gson, Application app) { | |
return new Retrofit.Builder() |
- Core:
- RxJava - https://github.com/ReactiveX/RxJava
- RxAndroid - https://github.com/ReactiveX/RxAndroid
- RxBinding - https://github.com/JakeWharton/RxBinding
- Applied Duality - http://www.applied-duality.com/
- Network:
- Retrofit - https://github.com/square/retrofit
- Storage:
- SqlBrite - https://github.com/square/sqlbrite
private ObservableManager obsManager = new ObservableManager(EventBus.getDefault()); | |
@Override | |
public Subscription getStores() { | |
// Get the observable if exists and is not too old | |
Observable<StoresList> observable = obsManager.get(ObservableManager.Types.STORES); | |
if (observable == null) { | |
// If is null create it and us cache to keep it in memeroy | |
observable = api.getStoresList() | |
.compose(applySchedulers(api.getStoresList())) |
/** | |
* Custom Scroll listener for RecyclerView. | |
* Based on implementation https://gist.github.com/ssinss/e06f12ef66c51252563e | |
*/ | |
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener { | |
public static String TAG = "EndlessScrollListener"; | |
private int previousTotal = 0; // The total number of items in the dataset after the last load | |
private boolean loading = true; // True if we are still waiting for the last set of data to load. | |
private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more. |
// Make a custom Gson instance, with a custom TypeAdapter for each wrapper object. | |
// In this instance we only have RealmList<RealmInt> as a a wrapper for RealmList<Integer> | |
Type token = new TypeToken<RealmList<RealmInt>>(){}.getType(); | |
Gson gson = new GsonBuilder() | |
.setExclusionStrategies(new ExclusionStrategy() { | |
@Override | |
public boolean shouldSkipField(FieldAttributes f) { | |
return f.getDeclaringClass().equals(RealmObject.class); | |
} |
public class SwipeRefreshLayoutToggleScrollListener extends RecyclerView.OnScrollListener { | |
private List<RecyclerView.OnScrollListener> mScrollListeners = new ArrayList<RecyclerView.OnScrollListener>(); | |
private int mExpectedVisiblePosition = 0; | |
private SwipeRefreshLayout mSwipeLayout; | |
public SwipeRefreshLayoutToggleScrollListener(SwipeRefreshLayout swipeLayout) { | |
mSwipeLayout = swipeLayout; | |
} | |
public void addScrollListener(RecyclerView.OnScrollListener listener){ | |
mScrollListeners.add(listener); |
This guide is a first draft (that will end up in the official docs) on writing resilient code for production with the Couchbase Java SDK. At the end, the reader will be able to write code that withstands bugs, latency issues or anything else that can make their application fail.
Note that lots of concepts can be applied for both synchronous and asynchronous access. When necessary, both patterns are discussed separately. Also, the focus is on database interaction, but if you are using RxJava as part of your stack you can apply most of the principles there as well (and should!).
When working with Observables, it is important to understand the difference between cold and hot. Cold Observables will start to emit events once a Observer subscribes, and will do it "fresh" for each Observer. Hot Observables instead are starting to emit data as soon as it becomes available, and will return the same (or parts of the same)
import android.support.v7.widget.LinearLayoutManager; | |
import android.support.v7.widget.RecyclerView; | |
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener { | |
public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName(); | |
private int previousTotal = 0; // The total number of items in the dataset after the last load | |
private boolean loading = true; // True if we are still waiting for the last set of data to load. | |
private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more. | |
int firstVisibleItem, visibleItemCount, totalItemCount; |