lokesh kumar lokesh kumar - 5 months ago 52
Android Question

how to solve this nullPointerException in funtion call in android?

This is a music player app. It has a MainActivity.java , MusicService.java , SongAdater.java and Song.java .

MainActivity.java

public class MainActivity extends AppCompatActivity {
public ArrayList<Song> songList;
private ListView songView;
private MusicService musicSrv;
private Intent playIntent;
pr1ivate boolean musicBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
songView = (ListView) findViewById(R.id.song_list);
songList = new ArrayList<Song>();
getSongList();

SongAdapter songAdt = new SongAdapter(this,songList);
songView.setAdapter(songAdt);

musicSrv.setList(songList);

}


private ServiceConnection musciConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder) service;
musicSrv = binder.getService();
musicBound = true;

}

@Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};

@Override
protected void onStart() {
super.onStart();

if(playIntent == null){
playIntent = new Intent(this,MusicService.class);
bindService(playIntent,musciConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
public void songPicked(View view){
musicSrv.setSong(Integer.parseInt(view.getTag().toString()));
musicSrv.playSong();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id){
case R.id.action_shuffle: break;
case R.id.action_end:
stopService(playIntent);
musicSrv=null;
System.exit(0);
break;
}
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}


@Override
public void onDestroy(){
stopService(playIntent);
musicSrv=null;
super.onDestroy();
}



public void getSongList(){
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri,null,null,null,null);

if(musicCursor!=null && musicCursor.moveToFirst()){
int titleCoulmn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex((MediaStore.Audio.Media._ID));
int artistColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);

do{
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleCoulmn);
String thisArtist = musicCursor.getString(artistColumn);
Log.d("getlist",thisTitle);
songList.add(new Song(thisId,thisTitle,thisArtist));
}while(musicCursor.moveToNext());

}
}


}

MusicService.java // service

public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,MediaPlayer.OnCompletionListener {
private MediaPlayer mediaPlayer;
private ArrayList<Song> songs = new ArrayList<Song>() ;
private int songPosn;
private final IBinder musicBind = new MusicBinder();
@Nullable
@Override

public IBinder onBind(Intent intent) {
return musicBind;
}

@Override
public void onCompletion(MediaPlayer mp) {

}

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}

@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}

@Override
public void onCreate(){
super.onCreate();
songPosn=0;
mediaPlayer = new MediaPlayer();
initMusicPlayer();
}
public void initMusicPlayer(){
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
}
public void setList(ArrayList<Song> thisSong){
songs = thisSong;
}


public class MusicBinder extends Binder{
MusicService getService(){
return MusicService.this;
}
}
@Override
public boolean onUnbind(Intent intent){
mediaPlayer.stop();
mediaPlayer.release();
return false;
}

public void playSong(){
mediaPlayer.reset();
setList();
Song playSong = songs.get(songPosn);
Log.e("play",playSong.toString());
long currSong = playSong.getID();
Uri trackUri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, currSong);
try {
mediaPlayer.setDataSource(getApplicationContext(),trackUri);
} catch (IOException e) {
e.printStackTrace();
}
// mediaPlayer= MediaPlayer.create(getApplicationContext(), trackUri);


mediaPlayer.prepareAsync();
}
public void setSong(int songIndex){
songPosn = songIndex;
}}


When I try to pass the songList to the setList() method of MusicService.java it shows nullPointerExcetion. When I comment out the code -
musicServ.setList(songList)
, the app doesn't crash. The issue is in that line only, I guess. Please help me solve this issue.

Answer

When I try to pass the songList to setList() method of MusicService.java it shows nullPointerExcetion. When i comment out the code - musicServ.setList(songList) , the app doesnt crash.The issue is in that line only,i guess. please help me solve this issue.

first of all, you are binding your service in onStart which is called after onCreate (you can read more here). So there is reason why musicSrv could be initialized in onCreate. On the other hand bindService is not a blocking call. Calling bindService doesn't guarantee you a connection to your Service. That's why you provide a ServiceConnection's object. Only when onServiceConnected is called your musicSrv is correctly initialized, and only then you can start using it. Moving musicServ.setList(songList) into the onServiceConnected after musicSrv = binder.getService() will fix your crash