Content Provider Calling API for Global Search

We are trying to connect our AndroidTV application to add results to the global search. I had a problem when I cannot make an api call to get the results, because the system calls my content provider in the main thread.

@Override public Cursor query(Uri uri, String[] projection, String search, String[] selectionArgs, String searchOrder) { ... Logic here that calls the API using RxJava / Retrofit return cursor; } <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/foo" android:searchSettingsDescription="@string/foo_results" android:includeInGlobalSearch="true" android:searchSuggestAuthority="com.foo.search.provider" android:searchSuggestIntentAction="android.intent.action.VIEW" /> <provider android:authorities="com.foo.search.provider" android:name=".search.GlobalSearchProvider" android:exported="true"/> 

When I do a global search, I see that the ContentProvider # request is being called. If I try to make an api call in the current thread, I get a network patch.

I tried to change the cursor, which changed the data, but also was not successful.

 getContext().getContentResolver().notifyChange(Uri.parse("content://com.foo.test"), null); ... cursor.setNotificationUri(getContext().getContentResolver(), Uri.parse("content://com.foo.test")); 

In any case, can I get the OS to call the content provider in a separate thread, or at least notify the search that the cursor has new content?

thanks

+6
source share
3 answers

One solution might be to install a content provider process

 android:process:":androidtv" 

and set ThreadPolicy to LAX just before making a network call

 ThreadPolicy tp = ThreadPolicy.LAX; StrictMode.setThreadPolicy(tp); 

By launching the contentprovider in another process, even if the request is executed in the main thread, this will not affect the operation of your interface.

+6
source

SEPARATE RESPONSE

I myself experienced this problem, and I had to rely on the decision made by the solution. However, I noticed that there is a noticeable lag when entering into the Global Search field. This lag:

  • Caused by the application, since its removal makes the backlog disappear.
  • Most likely due to the synchronous wait in the requested applications - since our application performs two network requests, the query() method takes time to complete, resulting in a lag

I found out that a separate process ( :androidtv ) is not needed. By setting the ThreadPolicy.LAX configuration, the network request will be executed without the NetworkOnMainThreadException metadata.

I still do not understand why there is a backlog.


ORIGINAL RESPONSE

I do not believe that the accepted answer, although it certainly works, is the right way.

After calling the query() method, you must create a new thread / task / task to make a network call (therefore, avoiding NetworkOnMainThreadException ), which will update the adapter after receiving the desired data.

There are different ways to do this. You can use a callback or an event bus (e.g. Otto ). This is the method I call to update the adapter:

 public void updateSearchResult(ArrayList<Data> result) { mListRowAdapter.clear(); mListRowAdapter.addAll(0, result); HeaderItem header = new HeaderItem(0, "Search results", null); mRowsAdapter.add(new ListRow(header, mListRowAdapter)); } 
0
source

I also struggled with this since I did not find a currently acceptable answer to blocking the user interface.

However, according to Mark Bouchinger of the Google TV team, this is only a problem with the emulator. In later builds (for example, in currently available hardware), search providers are called in the background thread, which completely fixes the problem.

I was able to test it on the Nexus Player and confirm that it works correctly.

Source: https://plus.google.com/+DanielCachapa/posts/dbNMoyoRGEi

0
source

Source: https://habr.com/ru/post/976085/


All Articles