如何在android中的函数调用中解决这个nullPointerException?

时间:2015-12-12 17:14:20

标签: android arraylist

这是一款音乐播放器应用。它有一个MainActivity.java,MusicService.java,SongAdater.java和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;
}}

当我尝试将songList传递给MusicService.java的setList()方法时,它会显示nullPointerExcetion。当我注释掉代码 - musicServ.setList(songList)时,应用程序不会崩溃。我想这个问题只在那条线上。请帮我解决这个问题。

1 个答案:

答案 0 :(得分:1)

  

当我尝试将songList传递给setList()方法时   MusicService.java它显示了nullPointerExcetion。当我评论出来的时候   代码 - musicServ.setList(songList),应用程序没有崩溃。问题是   我估计只在那条线上。请帮我解决这个问题。

首先,您要在onStart onCreate之后调用您的服务(您可以阅读更多here)。因此,musicSrv可以初始化onCreate是有原因的。另一方面,bindService不是阻止呼叫。致电bindService并不能保证您与Service建立联系。这就是您提供ServiceConnection对象的原因。只有在onServiceConnected被调用时,musicSrv才能正确初始化,然后才能开始使用它。在musicServ.setList(songList)之后将onServiceConnected移至musicSrv = binder.getService()将解决您的崩溃问题