用于自定义ListView布局的Android游标适配器 - 空指针异常错误

时间:2015-12-01 00:24:32

标签: java android sqlite listview simplecursoradapter

本网站上的第一篇文章,请原谅我的罪过。我正在尝试创建一个自定义ListView布局,该布局由我的SQLite Database Adapter类中的字段填充。下面是我尝试使用的方法,它在类的onCreate方法中调用,以及保存到数据库的按钮的onClick方法:

//Method to re-populate custom list view songlist_layout when a new entry is added
    private void populateSongList() {

        //Cursor to navigate through records of the database
        Cursor cursor = myDb.getAllRows();

        //Need two arrays to work with the Cursor. First is from field names
        String [] fromFieldNames = new String[] {DBAdapter.KEY_ROWID, 
                                                 DBAdapter.KEY_SONGTITLE, 
                                                 DBAdapter.KEY_SONGDURATION};

        //Second is int array
        int [] toViewIDs = new int [] {R.id.textViewSongNumber, R.id.textViewSongName, 
                                       R.id.textViewSongDuration};

        //Cursor Adapter Object
        SimpleCursorAdapter myCursorAdapter;
        myCursorAdapter = new SimpleCursorAdapter(getBaseContext(), 
                      R.layout.songlist_layout, cursor, fromFieldNames, toViewIDs,0);

        //Need to grab ListView from activity_add_song to set the adapter to it
        ListView songList = (ListView)findViewById(R.id.songsListView);
        songList.setAdapter(myCursorAdapter);
    }
 //Method to handle the click event of the Save button, adding the data into the database
    public void onClickSaveSong (View v) {

        //Song Title and duration are essential fields, so we want to check if they 
        //     have text before saving to the database
        if(!TextUtils.isEmpty(etSongTitle.getText().toString()) && 
           !TextUtils.isEmpty(etSongDuration.getText().toString())) {

            myDb.insertRow(etSongTitle.getText().toString(), 
                           etSongKey.getText().toString(), 
                           etSongTuning.getText().toString(),
                           etSongDuration.getText().toString());

            //Pop-up to inform user the Data has been saved
            Toast.makeText(getBaseContext(), "Song Added!", Toast.LENGTH_LONG).show();
        }//if

        //Otherwise a pop-up to tell the user to enter the essential info
        else {Toast.makeText(getBaseContext(), "Enter Title and Duration", 
              Toast.LENGTH_LONG).show();}

        //Call to repopulate songs ListView
        populateSongList();

    }//onClickSaveSong()

ListView的自定义XML布局包含三个TextView来保存songNumber,songName和songDuration:

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textViewSongNumber"
        android:paddingRight="10dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textViewSongName"
        android:paddingRight="60dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textViewSongDuration"
        android:paddingRight="70dp"/>

我在其他地方读过这个问题可能是因为ListView从错误的ListView ID中获取 ListView songList = (ListView)findViewById(R.id.songsListView); 但是将它与ListView的XML Layout进行比较,我不知道会出现这种情况:

<ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/songsListView"
        android:layout_below="@+id/imageView"
        android:layout_centerHorizontal="true"
        android:layout_above="@+id/addSongButton" />

最后,logcat:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.blob.gigstrofinal/com.blob.gigstrofinal.AddSong}: java.lang.NullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at com.blob.gigstrofinal.AddSong.populateSongList(AddSong.java:121)
            at com.blob.gigstrofinal.AddSong.onCreate(AddSong.java:45)

我无法弄清楚这一点。我没有长时间使用Android,其中很多都是我的头脑,所以我很感激这方面的任何帮助。该应用程序适用于大学项目,下周即将发布!

编辑:我忘了指定,Null指针异常指向AddSong.java的第121行,它是:songList.setAdapter(myCursorAdapter);

我从AddSong类中的onCreate方法调用populateSongList()方法:

public class AddSong extends Activity {

    //Declare Database Adapter
    DBAdapter myDb;

    //Declare EditText objects to be used for each field in the SQLite Database
    EditText etSongTitle;
    EditText etSongKey;
    EditText etSongTuning;
    EditText etSongDuration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_song);


        //Initialise EditText objects by assigning them to the corresponding ID
        etSongTitle = (EditText)findViewById(R.id.editSongTitle);
        etSongKey = (EditText)findViewById(R.id.editSongKey);
        etSongTuning = (EditText)findViewById(R.id.editSongTuning);
        etSongDuration = (EditText)findViewById(R.id.editSongDuration);

        //Call method to open Database
        openDB();
        //Call to populate songs ListView
        populateSongList();
    }

再次使用AddSong.java的onClickSaveSong方法(请参阅原始帖子的第二个代码段。

EDIT2:activity_add_song.xml的全部内容:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.blob.gigstrofinal.AddSong"
    android:background="@color/colorPrimary"
    >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tvSongTitle"
        android:id="@+id/songTitle"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:textStyle="bold"
        android:textSize="13sp"
        android:textColor="@color/colorPrimary2" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/songTitle"
        android:id="@+id/editSongTitle"
        android:layout_alignParentStart="true"
        android:editable="true"
        android:inputType="text"
        android:background="#e6e6e6"
        android:textColor="@color/colorPrimary3"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tvKey"
        android:id="@+id/songKey"
        android:textStyle="bold"
        android:textSize="13sp"
        android:textColor="@color/colorPrimary2"
        android:layout_marginTop="15dp"
        android:layout_below="@+id/editSongTitle"
        android:layout_alignParentStart="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editSongKey"
        android:layout_below="@+id/songKey"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/editSongTitle"
        android:background="#e6e6e6"
        android:inputType="text"
        android:textColor="@color/colorPrimary3" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tvTuning"
        android:id="@+id/songTuning"
        android:textStyle="bold"
        android:textSize="13sp"
        android:textColor="@color/colorPrimary2"
        android:layout_marginTop="13dp"
        android:layout_below="@+id/editSongKey"
        android:layout_alignParentStart="true" />


    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editSongTuning"
        android:layout_below="@+id/songTuning"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/editSongKey"
        android:background="#e6e6e6"
        android:textColor="@color/colorPrimary3"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tvDuration"
        android:id="@+id/songDuration"
        android:textStyle="bold"
        android:textSize="13dp"
        android:textColor="@color/colorPrimary2"
        android:layout_marginTop="15dp"
        android:layout_below="@+id/editSongTuning"
        android:layout_alignParentStart="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editSongDuration"
        android:layout_below="@+id/songDuration"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/editSongTuning"
        android:background="#e6e6e6"
        android:textColor="@color/colorPrimary3"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tvLyrics"
        android:id="@+id/songLyrics"
        android:textStyle="bold"
        android:textSize="13sp"
        android:textColor="@color/colorPrimary2"
        android:layout_below="@+id/editSongDuration"
        android:layout_alignParentStart="true"
        android:layout_marginTop="15sp"
        android:textIsSelectable="false" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textMultiLine"
        android:ems="10"
        android:id="@+id/editSongLyrics"
        android:layout_below="@+id/songLyrics"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/editSongDuration"
        android:background="#e6e6e6"
        android:layout_above="@+id/saveButton"
        android:layout_marginBottom="20dp"
        android:textColor="@color/colorPrimary3"/>

    <Button
        android:id="@+id/saveButton"
        android:text="@string/buttonSaveText"

        android:background="@color/colorPrimary"
        android:textColor="@color/colorPrimary2"
        android:textStyle="bold"
        android:textSize="11sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="19dp"
        android:layout_marginRight="22dp"
        android:onClick="onClickSaveSong"
        android:layout_alignParentBottom="true"
         />

    <Button
        android:id="@+id/backButton"
        android:text="@string/backButtonText"
        android:background="@color/colorPrimary"
        android:textColor="@color/colorPrimary2"
        android:textStyle="bold"
        android:textSize="11sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickBack"
        android:layout_alignBottom="@+id/saveButton"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_marginRight="19dp"
        />

</RelativeLayout>

或许值得一提的是,ListView本身并不位于Activity_add_song中,它位于另一个Activity activity_songs中。这会导致空指针异常吗?

4 个答案:

答案 0 :(得分:0)

请务必在populateSongList()之后致电setContentView()

请更具体地说明第121行的位置。

Caused by: java.lang.NullPointerException at com.blob.gigstrofinal.AddSong.populateSongList(AddSong.java:121)

答案 1 :(得分:0)

由于121行是这样的:

songList.setAdapter(myCursorAdapter);

这是你得到null的地方,然后songList或myCursorAdapter为null。 myCursorAdapter显然不为空,因此您可能在此行中使用findViewById方法的名称错误:

ListView songList = (ListView)findViewById(R.id.songsListView);

检查列表视图是否实际被调用&#34; songsListView&#34;在您的XML中 - 它可能不是。

答案 2 :(得分:0)

问题是ListView不在您在此活动中膨胀的布局xml中。

在onCreate()中调用它时:

fs.file-max = 2097152

vm.swappiness = 10
vm.dirty_ratio = 60
vm.dirty_background_ratio = 2

net.ipv4.tcp_synack_retries = 2

net.ipv4.ip_local_port_range = 1024 65535

net.ipv4.tcp_rfc1337 = 1

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_fin_timeout = 15

net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15

net.core.rmem_default = 31457280
net.core.rmem_max = 33554432

net.core.wmem_default = 31457280
net.core.wmem_max = 33554432

#net.core.somaxconn = 4096
net.core.somaxconn = 65535

net.ipv4.tcp_max_syn_backlog = 65535

net.core.netdev_max_backlog = 65536

net.core.optmem_max = 25165824

net.ipv4.tcp_mem = 65536 131072 262144
net.ipv4.udp_mem = 65536 131072 262144

net.ipv4.tcp_rmem = 8192 87380 16777216
net.ipv4.udp_rmem_min = 16384

net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_congestion_control = cubic

您正在将activity_add_song.xml布局xml扩展到当前窗口。

然后当你打电话:

setContentView(R.layout.activity_add_song);

它正在查看具有ID songsListView的ListView的当前膨胀布局。由于当前膨胀的布局(activity_add_song.xml)中没有songsListView,因此它将为null。

将处理ListView songList = (ListView)findViewById(R.id.songsListView); 的所有代码移动到使用ListView扩展布局的Activity。

答案 3 :(得分:0)

您的activity_add_song.xml应该包含您的代码中缺少的ListView

<ListView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/songsListView"
    android:layout_below="@+id/imageView"
    android:layout_centerHorizontal="true"
    android:layout_above="@+id/addSongButton" />

R.layout.songlist_layout应包含每行的布局

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New Text"
    android:id="@+id/textViewSongNumber"
    android:paddingRight="10dp"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New Text"
    android:id="@+id/textViewSongName"
    android:paddingRight="60dp"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New Text"
    android:id="@+id/textViewSongDuration"
    android:paddingRight="70dp"/>