-2

The listview sends an intent to musicplayer Activity. The intent contains integer values used to address songs and it works fine for small number of elements in say a Playlist (a listview) but for large number of songs it crashes (shown in Log below): Listview:

    final int size = lv.getAdapter().getCount();
    final String[] F= new String[size];
    final int Q[] = new int[size];
    // listening to single listitem click
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
            // getting listitem index
            TextView textView = (TextView) view.findViewById(android.R.id.text1);
            String songName = textView.getText().toString();//lv.getItemAtPosition(position).toString();

            Queuer(F,Q,size);
            //songIndex = manager.getSongIndex(songName, getApplicationContext());
            // Starting new intent
            Intent i = new Intent(getApplicationContext(), MusicPlayerActivity.class);
            Log.d("TAG", "onItemClick");
            //// Sending songIndex to PlayerActivity
            i.putExtra("size",size);
            i.putExtra("queue",Q);
            i.putExtra("filtered",true);
            //  Toast.makeText(getApplicationContext(), "Qi:" + Q[0], Toast.LENGTH_LONG).show();
            i.putExtra("start", position);
            startActivityForResult(i, 7);
        }
    });

Queuer method to store the names and indices of songs in arrays

void Queuer(String[] F,int[] Q, int size){
        for(int i=0;i<size;i++){
            View v = getListView().getChildAt(i);
            TextView tv= (TextView) v.findViewById(android.R.id.text1);
            F[i] = tv.getText().toString();
            Q[i] = manager.getSongIndex(F[i],getApplicationContext());
            Toast.makeText(getApplicationContext(), "SongName:" + F[i] , Toast.LENGTH_LONG).show();
        }
    }

Log:

01-07 00:03:50.293 27292-27292/com.imhotep.musicplayer E/AndroidRuntime: FATAL EXCEPTION: main Process: com.imhotep.musicplayer, PID: 27292 java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference at com.imhotep.musicplayer.FilteredTracksActivity.Queuer(FilteredTracksActivity.java:307) at com.imhotep.musicplayer.FilteredTracksActivity$4.onItemClick(FilteredTracksActivity.java:285) at android.widget.AdapterView.performItemClick(AdapterView.java:310) at android.widget.AbsListView.performItemClick(AbsListView.java:1213) at android.widget.AbsListView$PerformClick.run(AbsListView.java:3256) at android.widget.AbsListView$3.run(AbsListView.java:4190) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5706) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1033) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)

Need help with this. Adapter code:

        String[] columns = {MediaStore.Audio.Media.DATA,
                MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
                MediaStore.Audio.Media.DISPLAY_NAME,
                MediaStore.Audio.Media.MIME_TYPE};

        String where = android.provider.MediaStore.Audio.Media.ARTIST + "=?";
        String whereVal[] = { s };
        String orderBy = android.provider.MediaStore.Audio.Media.TITLE;
        Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                columns, where, whereVal, orderBy);

        //Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        //      new String[]{MediaStore.Audio.Media._ID,MediaStore.Audio.Media.TITLE}, where, whereVal, orderBy);

        String[] displayFields = new String[]{MediaStore.Audio.Media.TITLE};
        int[] displayViews = new int[]{android.R.id.text1};

        ListAdapter adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_1, cursor, displayFields,
                displayViews, 0);
        setListAdapter(adapter);
Amenhotep
  • 21
  • 7
  • 2
    It tells you exactly where the problem is. Since your using a `ListView` your views are being re-used. You need to use a `ViewHolder` to get the results you need. http://stackoverflow.com/a/19289890/1269953 – Pztar Jan 06 '17 at 18:42
  • `NullPointerException due to large sized array` **NO**. NPEs are **always** due to an object which has been referenced but not instanced . – Phantômaxx Jan 06 '17 at 19:31

1 Answers1

2

It happens because ListView recycles item views to save memory. So you can access null views still present. For this reason if you want to print all songs in your playlist (that should coincide with your ListView right?) you should get data objects from adapter. From there you can access object data directly, not from views objects.

firegloves
  • 5,581
  • 2
  • 29
  • 50
  • I thought of the same first but I couldnt figure-out /found-on-SO a way to store objects from ListAdapter directly into a String array... – Amenhotep Jan 06 '17 at 18:51
  • solved? if not post your adapter code please – firegloves Jan 06 '17 at 18:55
  • alright. Here is the ListAdapter code with the cursor that binds it. – Amenhotep Jan 06 '17 at 19:02
  • you are using a SimpleCursorAdapter, so it's not possible as I expected. But you can get your data from your Cursor, putting it back to the start and iterating on its values – firegloves Jan 06 '17 at 19:08
  • Yes, that's what I did in the second attempt. BUT the strings returned were complete paths of the songs. So I used substring() to trim it to the last "/" and get only the song name. BUT the song name returned was different from the one in list. (It had extra "-"+ and/or +"-" in it and there was no pattern in it so substring() couldn't be used anymore to match the actual song name. – Amenhotep Jan 06 '17 at 19:15
  • I think this one is a problem with your cursor or with your method to read data from it – firegloves Jan 06 '17 at 19:21