我有在APK内容提供商正在提供基于REST的搜索结果为多个客户端应用程序。
基本上,客户端请求经由内容解析器光标,然后触发一个意图的服务请求来触发搜索..
在提供者,光标返回到表,并且每个意图服务请求填充相应的表,并触发NotifyDataSetChanged。
作品真的很好..我遇到的唯一问题是,如果供应商被杀害由于某种原因光标上的客户端APK不会改变(做pkill的-9 com.myprovider.name测试),但应用程序不通知该供应商走了,就需要重新连接到数据库..所以它会继续火过服务的意图,光标永远不会被更新的b / C它不再依赖于底层数据库..
我通过我们的代码去试试,看看我们捕捉一些例外,也许隐藏了潜在的问题,但我没有看到它..
我试着明确地做一个cursor.close()在敲定/ onLowMemory /关机()的供应商..没有出现被触发。
我注意到,这发生在logcat的
09-10 13:58:03.015: I/ActivityThread(4268): Removing dead content provider: com.myprovider.name (called from the calling app)
任何方式来获得调用应用程序这个通知?
因此,一些研究之后,我有一个可行的解决方案,但会如果任何人有任何其他建议,他们将不胜感激。
由于这样的事实,我们使用的是ContentProvider的得到一个光标,然后就通过IntentService更新后端数据。 我们抓住光标当我们的用户在他们的搜索的第一个字符,如果光标数= 0,那么我们将展示一个空列表的消息,否则我们显示该光标的项目列表..
**注:有些光标处理可能需要进行调整了一下,我没有看到任何崩溃瓦特/有光标撕开我们的适配器,成为空,但您的里程可能会有所不同。(这是关于如何使用contentProviderClient())
**注意:每文档,你必须释放contentProviderClient()时不再使用。
由于内容提供商应该返回一个类型,我们可以做以下..
所以我们定义一个成员变量
private ContentProviderClient contentProviderClient = null;
然后,当我们的用户改变了我们最终调用搜索字符串
public void setFilter( String searchFilter ) {
searchedString = !TextUtils.isEmpty(filter) ? filter : "";
boolean reload = false; // Reloads content provider
// contentProvider is null on first connection, assumed to be up on
// subsequent connections as we only close the cursor and
// contentProviderClient when we exit
if (contentProviderClient != null) {
try {
// getType will throw an exception if the instance of the
// contentProvider went away (killed by user/memory collection etc)
contentProviderClient.getType(searchFactoryUri);
} catch (RemoteException e) {
if( searchAdapter != null ) {
Cursor cursor = searchAdapter.getCursor();
cursor = null;
reload = true;
contentProviderClient.release();
}
}
}
// This is for first search initialization or reloading cursor
// if the content provider went away for some unknown reason.
if( this.searchAdapter == null || reload ){
Cursor cursor = getActivity().getContentResolver().query(
MY_URI,
null,
null,
null,
null);
contentProviderClient = getActivity()
.getContentResolver()
.acquireContentProviderClient(MY_URI);
cursor.setNotificationUri(getActivity.getContentResolver(), MY_URI);
// DO what ever you need to after getting cursor, a cursor loader
// would be a better implementation here, but simplifying it as
// I don't want to over-complicate the example.
myList.setAdapter(searchAdapter);
}
getActivity().startService(MyUtil.getSearchIntent( MY_URI, searchedString );
}
@Override
public void onDestroy() {
super.onDestroy();
// Cleanup adapter, cursor, provider client
if (searchAdapter != null) {
searchAdapter.changeCursor(null); // Closes existing cursor
}
if (contentProviderClient != null) {
contentProviderClient.release(); // Release client
}
}