2014-10-01 26 views
6

Chúng tôi đang cố gắng kết nối ứng dụng AndroidTV của mình để nối thêm kết quả vào tìm kiếm toàn cầu. Tôi đang chạy vào một vấn đề mà tôi không thể thực hiện một cuộc gọi api để có được kết quả bởi vì hệ thống gọi nhà cung cấp nội dung của tôi trên chủ đề chính.API cuộc gọi trong nhà cung cấp nội dung để tìm kiếm toàn cầu

@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"/> 

Khi tôi thực hiện tìm kiếm toàn cầu, tôi có thể thấy truy vấn ContentProvider # được gọi. Nếu tôi cố gắng thực hiện cuộc gọi api trên luồng hiện tại, tôi sẽ nhận được một ngoại lệ về mạng.

Tôi đã cố gắng nhấn mạnh con trỏ mà dữ liệu đã thay đổi qua nhưng cũng không thành công.

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

Có cách nào tôi có thể buộc O.S gọi nhà cung cấp nội dung trên một chuỗi riêng biệt hoặc ít nhất thông báo cho tìm kiếm rằng con trỏ có nội dung mới không?

cảm ơn

Trả lời

6

Một trong những giải pháp có thể để hoàn thành quá trình cung cấp dịch vụ nội dung

android:process:":androidtv" 

và thiết lập ThreadPolicy LAX ngay trước khi thực hiện cuộc gọi mạng

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

Bằng cách chạy contentprovider trong một quy trình khác, ngay cả khi truy vấn chạy trên chuỗi chính, truy vấn đó sẽ không ảnh hưởng đến hoạt động giao diện người dùng của bạn

+0

Bạn có thể xem câu trả lời dưới đây không? – Sebastiano

+0

@dextor Tôi đoán bạn có thể thử thay đổi thứ tự trong đó searchableinfo của bạn xuất hiện trong danh sách SearchManager.getSearchablesInGlobalSearch(). Tôi nghĩ bạn có thể làm điều này bằng cách thay đổi tên của Hoạt động có thể tìm kiếm. Vì vậy, tìm kiếm ứng dụng của bạn sẽ được thực hiện cuối cùng bởi ứng dụng tìm kiếm, nhưng tôi không chắc liệu nó có hoạt động hay không. Hơn nữa, việc tạo một quy trình riêng biệt để truy vấn không chạy trên luồng chính, nếu bạn chỉ đặt chính sách lỏng lẻo, truy vấn sẽ vẫn chạy trong chuỗi chính và các hoạt động giao diện người dùng có thể bị trì hoãn hoặc bạn có thể nhận ANR – nandeesh

+0

Kết quả tìm kiếm của tôi đã được hiển thị dưới dạng kết quả cuối cùng, vì vậy đó không phải là kết quả. Tôi biết rằng chạy trên một quá trình riêng biệt "giải quyết" vấn đề, nhưng những gì tôi đã nhận thấy là sự chậm trễ kết quả là cách cao hơn chạy trên cùng một quá trình. Và tôi không thể hiểu tại sao. – Sebastiano

0

CHỈNH SỬA ĐÁP ỨNG

Tôi đã tự trải nghiệm vấn đề này và tôi phải dựa vào giải pháp được đề xuất của câu trả lời được chấp nhận. Tuy nhiên, tôi đã nhận thấy rằng có độ trễ đáng chú ý khi nhập vào ô 'Tìm kiếm toàn cầu'. chậm trễ này là:

  1. gây ra bởi ứng dụng, kể từ khi loại bỏ nó làm cho độ trễ biến mất
  2. Nhiều khả năng do chờ đợi đồng bộ trên các ứng dụng truy vấn - kể từ khi ứng dụng của chúng tôi thực hiện hai yêu cầu mạng, phương pháp query() cần có thời gian để hoàn thành, dẫn đến sự chậm trễ này

Tôi phát hiện ra rằng quá trình riêng biệt (:androidtv) là không cần thiết. Bằng cách đặt cấu hình ThreadPolicy.LAX, yêu cầu mạng sẽ vẫn thực thi mà không cần ném NetworkOnMainThreadException.

Tôi vẫn không hiểu tại sao tụt hậu lại ở đó.


ORIGINAL ĐÁP

Tôi không tin rằng câu trả lời được chấp nhận, trong khi chắc chắn nó hoạt động, là đúng cách làm điều đó.

Khi phương thức query() được gọi, bạn nên sinh ra một chuỗi/nhiệm vụ/công việc mới để thực hiện cuộc gọi mạng (do đó, tránh NetworkOnMainThreadException), sẽ cập nhật bộ điều hợp khi nhận được dữ liệu mong muốn.

Có nhiều cách khác nhau để thực hiện việc này.Bạn có thể sử dụng số gọi lại hoặc xe buýt sự kiện (ví dụ: Otto). Đây là phương pháp mà tôi gọi để cập nhật bộ điều hợp:

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

Tôi không thể khởi chạy một chuỗi riêng biệt vì không có cách nào tôi có thể liên lạc lại với khung AndroidTV mà dữ liệu trong con trỏ đã được cập nhật. – Darussian

+0

Tại sao không? (có lẽ tôi đang thiếu một cái gì đó) – Sebastiano

+0

Tôi không kiểm soát trong những gì khuôn khổ hiện, và họ không có thêm bất kỳ logic cho tôi để giao tiếp trở lại với nó. – Darussian

0

Tôi cũng đã gặp khó khăn với điều này vì tôi không tìm thấy câu trả lời hiện đang chấp nhận chặn giao diện người dùng chấp nhận được.

Tuy nhiên, theo Marc Bächinger từ nhóm Google TV, đây chỉ là vấn đề với trình mô phỏng. Trong các bản dựng mới hơn (chẳng hạn như các phần cứng trong phần cứng hiện có), các nhà cung cấp dịch vụ tìm kiếm được gọi trong một chủ đề nền, điều này tránh được vấn đề hoàn toàn.

Tôi đã có thể thử nghiệm trên Nexus Player và có thể xác nhận nó hoạt động bình thường.

Nguồn: https://plus.google.com/+DanielCachapa/posts/dbNMoyoRGEi

Các vấn đề liên quan