code: @Override
      public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
          if (DBG) Log.d(LOG_TAG, "runQueryOnBackgroundThread(" + constraint + ")");
          String query = (constraint == null) ? "" : constraint.toString();
          /**
           * for in app search we show the progress spinner until the cursor is returned with
           * the results.
           */
          Cursor cursor = null;
          if (mSearchView.getVisibility() != View.VISIBLE
                  || mSearchView.getWindowVisibility() != View.VISIBLE) {
              return null;
          }
          //mSearchView.getWindow().getDecorView().post(mStartSpinnerRunnable); // TODO:
          try {
              cursor = getSuggestions(query, QUERY_LIMIT);
              // trigger fill window so the spinner stays up until the results are copied over and
              // closer to being ready
              if (cursor != null) {
                  cursor.getCount();
                  return cursor;
              }
          } catch (RuntimeException e) {
              Log.w(LOG_TAG, "Search suggestions query threw an exception.", e);
          }
          // If cursor is null or an exception was thrown, stop the spinner and return null.
          // changeCursor doesn't get called if cursor is null
          // mSearchView.getWindow().getDecorView().post(mStopSpinnerRunnable); // TODO:
          return null;
      }
docs: Use the search suggestions provider to obtain a live cursor.  This will be called
  in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions).
  The results will be processed in the UI thread and changeCursor() will be called.