Good day! I decided to write an application player that scans the device, adds tracks to the playlist, and at the touch of a button opens it. But there was a problem: when you click on the "Playlist" button, an error java.lang.NullPointerException appears, indicating a ListView that is defined. Here is the code:


public ArrayAdapter mAdapter; public ListView mListView; private static final String[] EXTENSIONS = { ".mp3", ".wav", ".ogg", ".mus", ".aac" }; public List<String> trackNames; public List<String> trackArtworks; 

 public String[] getTracks() { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) || Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY)) { path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); String[] temp = path.list(); return temp; } else { Toast.makeText(getBaseContext(), "SD-карта не может быть прочитана или повреждена", Toast.LENGTH_LONG).show(); } return null; } public void addTracks(String[] temp) { if (temp != null) { for (int i = 0; i < temp.length; i++) { if (trackChecker(temp[i])) { trackNames.add(temp[i]); trackArtworks.add(temp[i].substring(0, temp[i].length() - 4)); ListView mListView = (ListView) findViewById(R.id.listsong_screen); ArrayAdapter mAdapter = new ArrayAdapter(this, R.layout.listsong_item, trackNames); } } Toast.makeText(getBaseContext(), "Загружено " + Integer.toString(trackNames.size()) + " треков", Toast.LENGTH_SHORT).show(); } } private boolean trackChecker(String trackToTest) { for (int j = 0; j < EXTENSIONS.length; j++) { if (trackToTest.contains(EXTENSIONS[j])) { return true; } } return false; } private void loadTrack() { if (mediaPlayer != null) { dispose(); } if (trackNames.size() > 0) { loadMusic(); } } 

 Button playlist = (Button) findViewById(R.id.playlistbutton); playlist.setOnClickListener(new OnClickListener(this) { public void onClick(View v) { mListView.setAdapter(mAdapter) } }); 
  • Obviously, mListView is null at the time the button is clicked. - falstaf

2 answers 2

Comment out the mListView.setAdapter (mAdapter). It does not crash, then the case is in this line. Then check on mAdapter! = Null, etc. In general, in my opinion, it is better to first install the adapter (initiated, but empty), and then when adding the data to notifyDataSetChanged (). And on the button, do not install the adapter, but run the update of the list. At the time of the click, it’s not clear if you already started addTracks, where, as I understand it, the adapter is initialized and whether this function has worked. The simplest one, on click: {getTracks (); mListView.setAdapter (mAdapter); }, then everything should work, but since everything is in the tracks, it can slow down.

Now reread the question.

and by pressing the button opens one.

Well, do just that by clicking: add a list to the markup, change the visibility, become disabled, etc. You can, again, run the update, if the list during the program can change. Installing the adapter every time is bad, IMHO.

    As written in the comment while clicking on the button, the onClick method is onClick . Inside it, the mListView object calls the setAdapter() method. Most likely at the moment mListView simply not initialized and the compiler throws a NullPointerException

    The solution is to initialize the mListView object by:

     mListView = (ListView) findViewById(R.id.lv_myList); 

    Where lv_myList is the id of the control from xml

     <ListView android:id="@+id/lv_myList" ...... /> 

    Initialization is desirable at the beginning of the onCreate method (in the same place where the button is initialized)

    • I tried to do this, but still throws a nullpointerexception exception. Maybe it's in the row mListView.setAdapter (mAdapter)? Can a ListView supply an ArrayAdapter <String> as an adapter? And more: this class is inherited from Activity, but not from ListActivity. - Helisia