Android的指针错误 - "确保光标从它访问数据之前,正确初始化..." [英] Android cursor error - "make sure cursor is initialized correctly before accessing data from it..."

查看:309
本文介绍了Android的指针错误 - "确保光标从它访问数据之前,正确初始化..."的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个活动,其中一个viewflipper显示了包含从mediastore艺术家,这onitem单击按选定的艺术家,这反过来又在该专辑显示歌曲显示专辑列表清单。一旦一首歌曲被点击,它应该填充字符串'标题'一个TextView。

直到此时,所有的光标都工作正常,但最后人似乎被放到了位置不知。谁能告诉我,为什么logcat的告诉我:

  05-07 23:58:54.195:E / AndroidRuntime(1961年):java.lang.IllegalStateException:无法读取第3行,列-1从CursorWindow。确保光标从它访问数据之前,正确初始化。
 

,这取决于艺术家/专辑/歌曲选择不能读取​​的特定行而异。在code是如下。非常感谢您的帮助。

 包music.flipper;

进口android.app.Activity;
进口android.database.Cursor;
进口android.os.Bundle;
进口android.provider.BaseColumns;
进口android.provider.MediaStore;
进口android.provider.MediaStore.Audio.AlbumColumns;
进口android.provider.MediaStore.Audio.ArtistColumns;
进口android.provider.MediaStore.Audio.AudioColumns;
进口android.provider.MediaStore.MediaColumns;
进口android.view.View;
进口android.widget.AdapterView;
进口android.widget.AdapterView.OnItemClickListener;
进口android.widget.ListView;
进口android.widget.SimpleCursorAdapter;
进口android.widget.TextView;
进口android.widget.ViewFlipper;

公共类MusicFlipper扩展活动实现OnItemClickListener {
    / **第一次创建活动时调用。 * /

    ViewFlipper viewflipper;
    光标光标;

    私人字符串currentList =艺术家;
    @燮pressWarnings(德precation)
    @覆盖
    公共无效的onCreate(包savedInstanceState){
            super.onCreate(savedInstanceState);

        的setContentView(R.layout.flipper);
        //设置主视图的鳍状肢。
        viewflipper =(ViewFlipper)findViewById(R.id.viewFlipper1);

        的String []列= {
                BaseColumns._ID,
                ArtistColumns.ARTIST
                };
        //列返回的每一行。

        光标= managedQuery(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
            列,NULL,NULL,NULL);

        ListView控件的ListView =(ListView控件)findViewById(R.id.listView1);
        listView.setOnItemClickListener(本);

        //设置onitemclicklistener在升降舵第一列表视图

        的String [] displayFields =新的String [] {ArtistColumns.ARTIST};
        //设置所有的艺术家姓名的数组'displayfields
        INT [] displayViews =新INT [] {R.id.rowItem};
        //行数显示和在哪里将它们绑定

        SimpleCursorAdapter适配器=新SimpleCursorAdapter(这一点,
            R.layout.row_item,光标,displayFields,displayViews);
        listView.setAdapter(适配器); }
        //就拿显示器领域的阵列,并绑定到匹配的显示行

     @燮pressWarnings(德precation)

    公共无效onItemClick(适配器视图<>一种,视图V,INT位置,长的id){

        如果(currentList.equals(艺术家)){
            如果(cursor.moveToPosition(位置)){
            //一旦某个项目被点击,将光标移动到该项目的立场

            字符串,其中= AudioColumns.ARTIST +=;
            //有鼠标的外观艺术家行内?

            串whereVal [] = {cursor.getString(光标
          .getColumnIndex(AlbumColumns.ARTIST))};
            //选择与所选择的艺术家的名字的特定行

            的String []列= {
                    BaseColumns._ID,
                    AudioColumns.ALBUM,
               };

                串排序依据= BaseColumns._ID;

            光标= managedQuery(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
                列,其中,whereVal,排序依据);

            ListView控件的ListView =(ListView控件)findViewById(R.id.listView2);
            listView.setOnItemClickListener(本);
            的String [] displayFields =新的String [] {AudioColumns.ALBUM};
            INT [] displayViews =新INT [] {R.id.rowItem};
            SimpleCursorAdapter适配器=新SimpleCursorAdapter(这一点,
                R.layout.row_item,光标,displayFields,displayViews);
            listView.setAdapter(适配器);
            currentList =相册;
            viewflipper.showNext();}

        }如果(currentList.equals(相册)){
            如果(cursor.moveToPosition(位置)){

                字符串,其中= AudioColumns.ALBUM
                +=?;

                串whereVal [] = {cursor.getString(光标
                .getColumnIndex(AlbumColumns.ALBUM))};

                的String []列= {
                        MediaColumns.DATA,
                        BaseColumns._ID,
                        MediaColumns.TITLE,
                        MediaColumns.DISPLAY_NAME,
                        MediaColumns.MIME_TYPE,
                   };

                    串排序依据= MediaColumns.TITLE;

                光标= managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    列,其中,whereVal,排序依据);

                ListView控件的ListView =(ListView控件)findViewById(R.id.listView3);
                listView.setOnItemClickListener(本);
                的String [] displayFields =新的String [] {MediaColumns.TITLE};
                INT [] displayViews =新INT [] {R.id.rowItem};
                SimpleCursorAdapter适配器=新SimpleCursorAdapter(这一点,
                    R.layout.row_item,光标,displayFields,displayViews);
                listView.setAdapter(适配器);
                currentList.equals(诗经);
                viewflipper.showNext();}


        }如果(currentList.equals(诗经)){
            如果(cursor.moveToPosition(位置)){

                字符串标题= cursor.getString(cursor.getColumnIndex(MediaColumns.TITLE));

                TextView的myTextView =(TextView中)findViewById(R.id.title);
                myTextView.setText(职称);

            }
        }
    }
}
 

解决方案

现在的问题是该行中,它在列。

 无法读取第3行,山坳** ** -1从CursorWindow。确保光标从它访问数据之前,正确初始化。
 

它基本上是说,你的MediaColumns.TITLE列未在游标存在。这是事实。这不是你的第一个光标(即它引用的一个)。你的其它光标都在如果语句,使走出去的范围,只留下第一个。

您既可以重新拉光标就像你在如果语句的其他部分呢,还是找一些方法来坚持你最后得到光标如果语句。

修改

这是pretty的简单修复,使光标一类变量。另外,我也不会继续再使用光标。标签他们somethign个人和描述性的,它会帮助你保持可读性在code。我可以做这样的:

 公共类MusicFlipper扩展活动实现OnItemClickListener {
    私人光标artistCursor;
    私人光标albumCursor;
 

然后你叫他们像你这样的人,但使用个人的名字。

  albumCursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                列,其中,whereVal,排序依据);
 

既然你宣布它作为一个类变量也将可通过全班所以在最后一部分,你会怎么做:

 如果(currentList.equals(诗经)){
    如果(albumCursor.moveToPosition(位置)){
            字符串标题= albumCursor.getString(albumCursor.getColumnIndex(MediaColumns.TITLE));
            TextView的myTextView =(TextView中)findViewById(R.id.title);
            myTextView.setText(职称);
    }
}
 

I've got an activity where a viewflipper shows a list containing the artists from mediastore, which onitem click display a list of albums by the chosen artist, which in turn displays the songs on that album. Once a song is clicked, it should populate a textview with the string 'title'.

Until this point, all of the cursors are working fine, but the very last one seems to get put out of position somehow. Could anyone tell me why logcat is telling me:

05-07 23:58:54.195: E/AndroidRuntime(1961): java.lang.IllegalStateException: Couldn't read row 3, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

The particular row which cannot be read varies depending on which artist/album/song is chosen. The code is as follows. Thank you very much for your help.

package music.flipper;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AlbumColumns;
import android.provider.MediaStore.Audio.ArtistColumns;
import android.provider.MediaStore.Audio.AudioColumns;
import android.provider.MediaStore.MediaColumns;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.ViewFlipper;

public class MusicFlipper extends Activity implements OnItemClickListener {
    /** Called when the activity is first created. */

    ViewFlipper viewflipper;
    Cursor cursor;

    private String currentList = "Artist";
    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

        setContentView(R.layout.flipper);
        //set the main view to flipper.
        viewflipper = (ViewFlipper) findViewById(R.id.viewFlipper1);

        String[] columns = { 
                BaseColumns._ID,
                ArtistColumns.ARTIST 
                };
        //The columns to return for each row.   

        cursor = managedQuery(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
            columns, null, null, null);

        ListView listView = (ListView) findViewById(R.id.listView1);
        listView.setOnItemClickListener(this);

        //set an onitemclicklistener to the first listview in flipper

        String[] displayFields = new String[] { ArtistColumns.ARTIST };
        //set all the artist names to the array 'displayfields'
        int[] displayViews = new int[] { R.id.rowItem };
        //number of rows to display and where to bind them

        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            R.layout.row_item, cursor, displayFields, displayViews);
        listView.setAdapter(adapter); }
        //Take the display fields array, and bind to the matching display row

     @SuppressWarnings("deprecation")

    public void onItemClick(AdapterView<?> a, View v, int position, long id) {

        if( currentList.equals("Artist")) {
            if (cursor.moveToPosition(position)) {
            //once an item is clicked, move the cursor to that items position

            String where = AudioColumns.ARTIST + "=?";
            // Have the cursor look within the artist row?

            String whereVal[] = { cursor.getString(cursor
          .getColumnIndex(AlbumColumns.ARTIST)) };
            //Choose the particular row with the chosen artist's name

            String[] columns = {
                    BaseColumns._ID,
                    AudioColumns.ALBUM,
               };

                String orderBy = BaseColumns._ID;

            cursor = managedQuery(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
                columns, where, whereVal, orderBy);

            ListView listView = (ListView) findViewById(R.id.listView2);
            listView.setOnItemClickListener(this);
            String[] displayFields = new String[] { AudioColumns.ALBUM };
            int[] displayViews = new int[] { R.id.rowItem };
            SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                R.layout.row_item, cursor, displayFields, displayViews);
            listView.setAdapter(adapter);
            currentList = "Album";
            viewflipper.showNext();}

        } if (currentList.equals("Album")) {
            if (cursor.moveToPosition(position)) {

                String where = AudioColumns.ALBUM
                + "=?";

                String whereVal[] = { cursor.getString(cursor
                .getColumnIndex(AlbumColumns.ALBUM)) };

                String[] columns = {
                        MediaColumns.DATA,
                        BaseColumns._ID,
                        MediaColumns.TITLE,
                        MediaColumns.DISPLAY_NAME,
                        MediaColumns.MIME_TYPE,
                   };

                    String orderBy = MediaColumns.TITLE;

                cursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    columns, where, whereVal, orderBy);

                ListView listView = (ListView) findViewById(R.id.listView3);
                listView.setOnItemClickListener(this);
                String[] displayFields = new String[] { MediaColumns.TITLE };
                int[] displayViews = new int[] { R.id.rowItem };
                SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                    R.layout.row_item, cursor, displayFields, displayViews);
                listView.setAdapter(adapter);
                currentList.equals("Songs");
                viewflipper.showNext();}


        } if (currentList.equals("Songs")) {
            if (cursor.moveToPosition(position)) {

                String title = cursor.getString(cursor.getColumnIndex(MediaColumns.TITLE));

                TextView myTextView = (TextView) findViewById(R.id.title);
                myTextView.setText(title);

            }
        }
    }
}

解决方案

The problem isn't in the row, it's in the column.

Couldn't read row 3, **col -1** from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

It's basically saying that your MediaColumns.TITLE column doesn't exist in the cursor. Which is true. It's not in your first cursor (the one that it is referencing). Your other cursors are all within if statements so go out of scope and leave only the first one.

You can either re-pull the cursor like you do in the other portions of the if statement, or find some way to persist the cursor you got from the last if statement.

EDIT

It's pretty simple to fix, make the cursor a class variable. Also, I wouldn't keep re-using "cursor". Label them somethign individual and descriptive, it'll help you maintain readability in your code. I might do it like this:

public class MusicFlipper extends Activity implements OnItemClickListener {
    private Cursor artistCursor;
    private Cursor albumCursor;

Then you call them like you were but use the individual names.

albumCursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                columns, where, whereVal, orderBy);

Since you declared it as a class variable it will be available through the whole class so in the last part you'd do:

if (currentList.equals("Songs")) {
    if (albumCursor.moveToPosition(position)) {
            String title = albumCursor.getString(albumCursor.getColumnIndex(MediaColumns.TITLE));
            TextView myTextView = (TextView) findViewById(R.id.title);
            myTextView.setText(title);
    }
}

这篇关于Android的指针错误 - &QUOT;确保光标从它访问数据之前,正确初始化...&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆