sqlbrite/src/main/java/com/squareup/sqlbrite3/BriteContentResolver.java
@CheckResult @NonNull
  public QueryObservable createQuery(@NonNull final Uri uri, @Nullable final String[] projection,
      @Nullable final String selection, @Nullable final String[] selectionArgs, @Nullable
      final String sortOrder, final boolean notifyForDescendents) {
    final Query query = new Query() {
      @Override public Cursor run() {
        long startNanos = nanoTime();
        Cursor cursor = contentResolver.query(uri, projection, selection, selectionArgs, sortOrder);

        if (logging) {
          long tookMillis = NANOSECONDS.toMillis(nanoTime() - startNanos);
          log("QUERY (%sms)\n  uri: %s\n  projection: %s\n  selection: %s\n  selectionArgs: %s\n  "
                  + "sortOrder: %s\n  notifyForDescendents: %s", tookMillis, uri,
              Arrays.toString(projection), selection, Arrays.toString(selectionArgs), sortOrder,
              notifyForDescendents);
        }

        return cursor;
      }
    };
    Observable<Query> queries = Observable.create(new ObservableOnSubscribe<Query>() {
      @Override public void subscribe(final ObservableEmitter<Query> e) throws Exception {
        final ContentObserver observer = new ContentObserver(contentObserverHandler) {
          @Override public void onChange(boolean selfChange) {
            if (!e.isDisposed()) {
              e.onNext(query);
            }
          }
        };
        contentResolver.registerContentObserver(uri, notifyForDescendents, observer);
        e.setCancellable(new Cancellable() {
          @Override public void cancel() throws Exception {
            contentResolver.unregisterContentObserver(observer);
          }
        });

        if (!e.isDisposed()) {
          e.onNext(query); // Trigger initial query.
        }
      }
    });
    return queries //
        .observeOn(scheduler) //
        .compose(queryTransformer) // Apply the user's query transformer.
        .to(QUERY_OBSERVABLE);
  }
@CheckResult @NonNull
  public QueryObservable createQuery(@NonNull final Uri uri, @Nullable final String[] projection,
      @Nullable final String selection, @Nullable final String[] selectionArgs, @Nullable
      final String sortOrder, final boolean notifyForDescendents) {
    final Query query = new Query() {
      @Override public Cursor run() {
        long startNanos = nanoTime();
        Cursor cursor = contentResolver.query(uri, projection, selection, selectionArgs, sortOrder);

        if (logging) {
          long tookMillis = NANOSECONDS.toMillis(nanoTime() - startNanos);
          log("QUERY (%sms)\n  uri: %s\n  projection: %s\n  selection: %s\n  selectionArgs: %s\n  "
                  + "sortOrder: %s\n  notifyForDescendents: %s", tookMillis, uri,
              Arrays.toString(projection), selection, Arrays.toString(selectionArgs), sortOrder,
              notifyForDescendents);
        }

        return cursor;
      }
    };
    Observable<Query> queries = Observable.create(new ObservableOnSubscribe<Query>() {
      @Override public void subscribe(final ObservableEmitter<Query> e) throws Exception {
        final ContentObserver observer = new ContentObserver(contentObserverHandler) {
          @Override public void onChange(boolean selfChange) {
            if (!e.isDisposed()) {
              e.onNext(query);
            }
          }
        };
        contentResolver.registerContentObserver(uri, notifyForDescendents, observer);
        e.setCancellable(new Cancellable() {
          @Override public void cancel() throws Exception {
            contentResolver.unregisterContentObserver(observer);
          }
        });

        if (!e.isDisposed()) {
          e.onNext(query); // Trigger initial query.
        }
      }
    });
    return queries //
        .observeOn(scheduler) //
        .compose(queryTransformer) // Apply the user's query transformer.
        .to(QUERY_OBSERVABLE);
  }
Create an observable which will notify subscribers with a {@linkplain Query query} for
execution. Subscribers are responsible for <b>always</b> closing {@link Cursor} instance
returned from the {@link Query}.
<p>
Subscribers will receive an immediate notification for initial data as well as subsequent
notifications for when the supplied {@code uri}'s data changes. Unsubscribe when you no longer
want updates to a query.
<p>
Since content resolver triggers are inherently asynchronous, items emitted from the returned
observable use the {@link Scheduler} supplied to {@link SqlBrite#wrapContentProvider}. For
consistency, the immediate notification sent on subscribe also uses this scheduler. As such,
calling {@link Observable#subscribeOn subscribeOn} on the returned observable has no effect.
<p>
Note: To skip the immediate notification and only receive subsequent notifications when data
has changed call {@code skip(1)} on the returned observable.
<p>
<b>Warning:</b> this method does not perform the query! Only by subscribing to the returned
{@link Observable} will the operation occur.

@see ContentResolver#query(Uri, String[], String, String[], String)
@see ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)