android-SQLite查询使用ExpandableListViewSimpleCursorTreeAdapter在UI线程上运行

android-SQLite查询使用ExpandableListViewSimpleCursorTreeAdapter在UI线程上运行,第1张

概述我正在开发用于显示大量RSS提要的Android应用程序(是的,我知道已经有很多这样的应用程序).内容提供者支持要显示的数据,我想与API级别4向后兼容.我正在使用ExpandableListView来显示三个不同的RSSfeed的内容.ExpandableListView的适配器被实现为SimpleCursorTreeAdapter的子类:

我正在开发用于显示大量RSS提要的Android应用程序(是的,我知道已经有很多这样的应用程序).内容提供者支持要显示的数据,我想与API级别4向后兼容.

我正在使用ExpandableListVIEw来显示三个不同的RSS Feed的内容. ExpandableListVIEw的适配器被实现为SimpleCursorTreeAdapter的子类:

private class RSSFeedLatestlistadapter extends SimpleCursorTreeAdapter {    public static final String Feed_name_ColUMN = "Feedname";    public RSSFeedLatestlistadapter(Context ctx, Cursor groupCursor, int groupLayout,            String[] groupFrom, int[] groupTo, int childLayout, String[] childFrom,            int[] childTo) {        super(ctx, groupCursor, groupLayout, groupLayout, groupFrom, groupTo, childLayout, childFrom, childTo);    }    @OverrIDe    protected Cursor getChildrenCursor(final Cursor groupCursor) {        final String Feedname = groupCursor.getString(groupCursor.getColumnIndex(Feed_name_ColUMN));        return managed@R_502_5962@(LATEST_URI, null,                FeedItemColumns.category + " = ? AND " + FeedItemColumns.Feed + " = ?",                new String[] { mcategory.getID(), Feedname }, null);    }    @OverrIDe    protected voID bindGroupVIEw(VIEw vIEw, Context context, Cursor cursor, boolean isExpanded) {        super.bindGroupVIEw(vIEw, context, cursor, isExpanded);        // Bind group vIEw (impl details not important) ...    }    @OverrIDe    protected voID bindChildVIEw(VIEw vIEw, Context context, Cursor cursor, boolean isLastChild) {        super.bindChildVIEw(vIEw, context, cursor, isLastChild);        // Bind child vIEw (impl details not important) ...    }}

使用此设置,所有内容均按预期加载.但是,UI在列表内容加载期间随机挂起/结结.通常不足以获取ANR,但仍然很引人注目且非常烦人!

为了调试此问题,我启用了androID.os.StrictMode(很棒的新功能/工具btw!),并启动了模拟器(在AndroID 2.3上).加载列表内容时,将获得以下StrictMode输出:

D/StrictMode(  395): StrictMode policy violation; ~duration=1522 ms: androID.os.StrictMode$StrictModediskReadViolation: policy=23 violation=2D/StrictMode(  395):  at androID.os.StrictMode$AndroIDBlockGuardPolicy.onReadFromdisk(StrictMode.java:745)D/StrictMode(  395):  at androID.database.sqlite.sqliteDatabase.raw@R_502_5962@WithFactory(sqliteDatabase.java:1345)D/StrictMode(  395):  at androID.database.sqlite.sqlite@R_502_5962@Builder.@R_502_5962@(sqlite@[email protected]:330)D/StrictMode(  395):  at com.mycompany.myapp.provIDer.RSSFeedProvIDer.@R_502_5962@(RSSFeedProvIDer.java:128)D/StrictMode(  395):  at androID.content.ContentProvIDer$Transport.@R_502_5962@(ContentProvIDer.java:187)D/StrictMode(  395):  at androID.content.ContentResolver.@R_502_5962@(ContentResolver.java:262)D/StrictMode(  395):  at androID.app.Activity.managed@R_502_5962@(Activity.java:1550)D/StrictMode(  395):  at com.mycompany.myapp.activity.MultipleFeedsActivity$RSSFeedLatestlistadapter.getChildrenCursor(MultipleFeedsActivity.java:388)D/StrictMode(  395):  at androID.Widget.CursorTreeAdapter.getChildrenCursorHelper(CursorTreeAdapter.java:106)D/StrictMode(  395):  at androID.Widget.CursorTreeAdapter.getChildrenCount(CursorTreeAdapter.java:178)D/StrictMode(  395):  at androID.Widget.ExpandableListConnector.refreshExpGroupMetadataList(ExpandableListConnector.java:561)D/StrictMode(  395):  at androID.Widget.ExpandableListConnector.expandGroup(ExpandableListConnector.java:682)D/StrictMode(  395):  at androID.Widget.ExpandableListConnector.expandGroup(ExpandableListConnector.java:636)D/StrictMode(  395):  at androID.Widget.ExpandableListVIEw.expandGroup(ExpandableListVIEw.java:608)D/StrictMode(  395):  at com.mycompany.myapp.activity.MultipleFeedsActivity.onReceiveResult(MultipleFeedsActivity.java:335)D/StrictMode(  395):  at com.mycompany.myapp.service.FeedResultReceiver.onReceiveResult(FeedResultReceiver.java:40)D/StrictMode(  395):  at androID.os.ResultReceiver$MyRunnable.run(ResultReceiver.java:43)D/StrictMode(  395):  at androID.os.Handler.handleCallback(Handler.java:587)D/StrictMode(  395):  at androID.os.Handler.dispatchMessage(Handler.java:92)D/StrictMode(  395):  at androID.os.Looper.loop(Looper.java:123)D/StrictMode(  395):  at androID.app.ActivityThread.main(ActivityThread.java:3647)D/StrictMode(  395):  at java.lang.reflect.Method.invokeNative(Native Method)D/StrictMode(  395):  at java.lang.reflect.Method.invoke(Method.java:507)D/StrictMode(  395):  at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)D/StrictMode(  395):  at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:597)D/StrictMode(  395):  at dalvik.system.NativeStart.main(Native Method)

这似乎是合理的!在SimpleCursorTreeAdapter.getChildrenCursor()中,将在UI线程查询内容提供者,这当然是一个坏主意,它肯定会挂断UI!

我看了一下CursorTreeAdapter(SimpleCursorTreeAdapter的超类)的JavaDoc(API级别4),对于getChildrenCursor()它说:

“如果要异步查询提供程序以防止阻塞UI,则可以返回null,并在以后调用setChildrenCursor(int,Cursor).”

大!让我们开始吧!我更改了getChildrenCursor()的实现,以启动一个新任务,该任务负责执行查询并在适配器上设置子级光标.开始任务后,我只是在getChildrenCursor()中返回null:

@OverrIDeprotected Cursor getChildrenCursor(final Cursor groupCursor) {    final String Feedname = groupCursor.getString(groupCursor.getColumnIndex(Feed_name_ColUMN));    new RefreshChildrenCursorTask(groupCursor.getposition()).execute(Feedname);    return null;}

,其中RefreshChildrenCursorTask实现为:

private class RefreshChildrenCursorTask extends AsyncTask<String, VoID, Cursor> {    private int mGroupposition;    public RefreshChildrenCursorTask(int groupposition) {        this.mGroupposition = groupposition;    }    @OverrIDe    protected Cursor doInBackground(String... params) {        String Feedname = params[0];        return managed@R_502_5962@(LATEST_URI, null,                FeedItemColumns.category + " = ? AND " + FeedItemColumns.Feed + " = ?",                new String[] { mcategory.getID(), Feedname }, null);        }        @OverrIDe        protected voID onPostExecute(Cursor childrenCursor) {            mLatestlistadapter.setChildrenCursor(mGroupposition, childrenCursor);        }    }}

我在2.3模拟器上重新安装了该应用程序并启动了它.它像魅力一样,再见了无响应的用户界面!但是这种欢乐并没有持续很长时间……接下来要做的是在目标设备上运行相同的代码(在本例中为运行AndroID 2.2的三星galaxy S).然后,我在加载列表供稿内容期间遇到了以下异常:

E/AndroIDRuntime(23191): FATAL EXCEPTION: mainE/AndroIDRuntime(23191): java.lang.NullPointerExceptionE/AndroIDRuntime(23191):  at androID.Widget.SimpleCursorTreeAdapter.initFromColumns(SimpleCursorTreeAdapter.java:194)E/AndroIDRuntime(23191):  at androID.Widget.SimpleCursorTreeAdapter.initChildrenFromColumns(SimpleCursorTreeAdapter.java:205)E/AndroIDRuntime(23191):  at androID.Widget.SimpleCursorTreeAdapter.init(SimpleCursorTreeAdapter.java:186)E/AndroIDRuntime(23191):  at androID.Widget.SimpleCursorTreeAdapter.(SimpleCursorTreeAdapter.java:136)E/AndroIDRuntime(23191):  at com.mycompany.myapp.activity.MultipleFeedsActivity$RSSFeedLatestlistadapter.(MultipleFeedsActivity.java:378)E/AndroIDRuntime(23191):  at com.mycompany.myapp.activity.MultipleFeedsActivity.run(MultipleFeedsActivity.java:150)E/AndroIDRuntime(23191):  at androID.os.Handler.handleCallback(Handler.java:587)E/AndroIDRuntime(23191):  at androID.os.Handler.dispatchMessage(Handler.java:92)E/AndroIDRuntime(23191):  at androID.os.Looper.loop(Looper.java:123)E/AndroIDRuntime(23191):  at androID.app.ActivityThread.main(ActivityThread.java:4627)E/AndroIDRuntime(23191):  at java.lang.reflect.Method.invokeNative(Native Method)E/AndroIDRuntime(23191):  at java.lang.reflect.Method.invoke(Method.java:521)E/AndroIDRuntime(23191):  at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)E/AndroIDRuntime(23191):  at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:629)E/AndroIDRuntime(23191):  at dalvik.system.NativeStart.main(Native Method)

快速浏览一下SimpleCursorTreeAdapter的源代码可知,它无法应付从getChildrenCursor()异步返回的null.他们似乎已经在AndroID 2.3中解决了这个问题,但是您应该如何在AndroID的早期版本中解决它呢?我是否真的必须编写自己的CursorTreeAdapter实现才能异步刷新子游标?

是否有人遇到过同样的问题,甚至找到了(可行的)解决方法?如果没有,有人可以提示我如何进行!!我会很感激我能得到的任何帮助!

提前致谢!

问候,
雅各布

解决方法:

如果他们在2.3 SimpleCursorTreeAdapter中进行了修复,为什么不下载Java文件并将其包含在项目中并使用该版本而不是电话上的版本呢?

我没有看过代码,但是只要他们没有进行任何新的2.3 API调用,它就应该起作用.

总结

以上是内存溢出为你收集整理的android-SQLite查询使用ExpandableListView / SimpleCursorTreeAdapter在UI线程上运行全部内容,希望文章能够帮你解决android-SQLite查询使用ExpandableListView / SimpleCursorTreeAdapter在UI线程上运行所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1083029.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存