Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android SQLite查询使用ExpandableListView/SimpleCorsOrtreeAdapter在UI线程上运行_Android_Cursor_Expandablelistview_Ui Thread - Fatal编程技术网

Android SQLite查询使用ExpandableListView/SimpleCorsOrtreeAdapter在UI线程上运行

Android SQLite查询使用ExpandableListView/SimpleCorsOrtreeAdapter在UI线程上运行,android,cursor,expandablelistview,ui-thread,Android,Cursor,Expandablelistview,Ui Thread,我正在开发一个Android应用程序,用于显示大量RSS提要(是的,我知道已经有很多类似的应用程序)。要显示的数据由内容提供商支持,我希望与API级别4向后兼容 我正在使用一个ExpandableListView来显示三个不同RSS提要的内容。ExpandableListView的适配器作为SimpleCursorTreeAdapter的子类实现: private class RssFeedLatestListAdapter extends SimpleCursorTreeAdapter {

我正在开发一个Android应用程序,用于显示大量RSS提要(是的,我知道已经有很多类似的应用程序)。要显示的数据由内容提供商支持,我希望与API级别4向后兼容

我正在使用一个
ExpandableListView
来显示三个不同RSS提要的内容。
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 managedQuery(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.stricmode(很棒的新功能/工具,顺便说一下!),并启动了模拟器(在android2.3上)。加载列表内容时,我得到以下StrictMode输出:

D/StrictMode( 395): StrictMode policy violation; ~duration=1522 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=23 violation=2 D/StrictMode( 395): at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:745) D/StrictMode( 395): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345) D/StrictMode( 395): at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:330) D/StrictMode( 395): at com.mycompany.myapp.provider.RSSFeedProvider.query(RSSFeedProvider.java:128) D/StrictMode( 395): at android.content.ContentProvider$Transport.query(ContentProvider.java:187) D/StrictMode( 395): at android.content.ContentResolver.query(ContentResolver.java:262) D/StrictMode( 395): at android.app.Activity.managedQuery(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) ,其中,
RefreshChildrencersorTask
实现为:

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 managedQuery(LATEST_URI, null,
                FeedItemColumns.CATEGORY + " = ? AND " + FeedItemColumns.FEED + " = ?",
                new String[] { mCategory.getId(), feedName }, null);
        }

        @Override
        protected void onPostExecute(Cursor childrenCursor) {
            mLatestListAdapter.setChildrenCursor(mGroupPosition, childrenCursor);
        }
    }
}
快速查看一下
SimpleCursorTreeAdapter
的源代码,我发现它无法处理从
getChildrenCursor()
异步返回的null。他们似乎已经在Android 2.3中解决了这个问题,但在早期版本的Android中,你应该如何解决这个问题呢?我真的必须编写自己的
CursorTreeAdapter
实现才能异步刷新子游标吗

有没有人遇到过同样的问题,甚至找到了(可行的)解决办法?如果没有,谁能给我一个如何继续的提示我真的非常感谢能得到的任何帮助

提前谢谢

问候,,
Jacob

如果他们在2.3 SimpleCorSortreeAdapter中修复了它,为什么不下载java文件并将其包含在项目中,然后使用该版本而不是手机上的版本


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

感谢您的反馈,mp2526!我为我迟来的回复道歉

这是一个很好的建议!然而,我真的认为应该可以在API 8中这样做(异步检索子游标),并且我误解了任何东西。。。显然,这是不可能的(至少在使用
SimpleCursorTreeAdapter
时是不可能的)

无论如何,我对
SimpleCorSortreeAdapter
的API 8和API 9做了一个区别,他们在Android 2.3中所做的是
childFrom
groupFrom
列ID现在被延迟初始化,即不再在构造函数中。相反,这些成员现在在第一次调用
bindView()
时被初始化。这样,现在就可以异步检索子游标了。由于该类的公共API在API 4和API 9之间似乎没有任何更改(除了新方法
setViewText()
),因此使用该类的API版本9的解决方案应该可以正常工作,而不会发生更改!我试过了,成功了


非常感谢,mp2526

我只是想指出,我需要类似的功能,但是,我已经在使用从CursorTreeAdapter继承的自定义适配器,而不是使用SimpleCursorTreeAdapter。我的代码从getChildrenCursor()返回null,在我的2.0仿真器和Galaxy Tab(2.2)仿真器上运行良好。因此,也许创建一个自定义适配器就是解决方案
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 managedQuery(LATEST_URI, null,
                FeedItemColumns.CATEGORY + " = ? AND " + FeedItemColumns.FEED + " = ?",
                new String[] { mCategory.getId(), feedName }, null);
        }

        @Override
        protected void onPostExecute(Cursor childrenCursor) {
            mLatestListAdapter.setChildrenCursor(mGroupPosition, childrenCursor);
        }
    }
}
E/AndroidRuntime(23191): FATAL EXCEPTION: main E/AndroidRuntime(23191): java.lang.NullPointerException E/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$2.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)