这是一款音乐播放器应用。它有一个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)
时,应用程序不会崩溃。我想这个问题只在那条线上。请帮我解决这个问题。
答案 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()
将解决您的崩溃问题