我又回来了另一个NullPointerException。它表示标记的行有错误。但是,我无法弄清楚导致问题的原因。我确定id是正确的并确实存在。
这是我的代码:
MainActivity.java:
package com.bartkoppelmans.wavelength;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends Activity implements GestureDetector.OnGestureListener {
GestureDetector gestureDetector;
public static final boolean isCreated = false;
public MediaPlayer mediaPlayer;
Timer timer;
boolean musicBound=false;
private MusicService musicService;
private Intent playIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gestureDetector = new GestureDetector( this );
ImageView playButton = (ImageView) findViewById(R.id.albumImageView);
playButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
playButtonPressed();
}
});
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.musicSelectionOpenerFrameLayout);
frameLayout.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MusicSelection.class);
startActivity(intent);
overridePendingTransition(R.anim.slide_up_in, R.anim.slide_up_out);
}
});
}
//connect to the service
public final ServiceConnection musicConnection = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder)service;
//get service
musicService = binder.getService();
musicBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
//start and bind the service when the activity starts
@Override
public void onStart() {
super.onStart();
if(playIntent==null){
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
overridePendingTransition(R.anim.slide_down_in, R.anim.slide_down_out);
}
@Override
protected void onDestroy() {
mediaPlayer.release();
mediaPlayer = null;
super.onStop();
}
public void playButtonPressed() {
if (isCreated) {
if ( mediaPlayer.isPlaying() ) {
mediaPlayer.pause();
} else {
mediaPlayer.start();
}
}else {
updateTimer();
Toast.makeText(getApplicationContext(), "Please select song", Toast.LENGTH_LONG).show();
}
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent start, MotionEvent finish, float velocityX, float velocityY) {
return false;
}
@Override
public boolean onTouchEvent(MotionEvent me) {
return gestureDetector.onTouchEvent(me);
}
public void updateTimer() {
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
----------------------------final TextView timerTextView = (TextView)findViewById(R.id.timerTextView);
final ProgressBar timerProgressBar = (ProgressBar)findViewById(R.id.mainProgressbar);
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
timerTextView.post(new Runnable() {
@Override
public void run() {
int position = 5;
int duration = 10;
timerProgressBar.setMax(duration);
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
final String time = df.format(new Date(position)) + " / " + df.format(new Date(duration));
timerTextView.setText(time);
timerProgressBar.setProgress(position);
}
});
} else {
timer.cancel();
timer.purge();
}
}
});
}
}, 0, 100);
}
}
MusicService.java:
package com.bartkoppelmans.wavelength;
import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
import java.util.Timer;
public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
//media player
private MediaPlayer mediaPlayer;
//binder
private final IBinder musicBind = new MusicBinder();
Timer timer;
Handler handler;
public void onCreate(){
handler = new Handler();
//create the service
super.onCreate();
//create player
mediaPlayer = new MediaPlayer();
//initialize
initMusicPlayer();
}
public void initMusicPlayer(){
//set player properties
mediaPlayer.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//set listeners
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
}
//binder
public class MusicBinder extends Binder {
MusicService getService() {
return MusicService.this;
}
}
//activity will bind to service
@Override
public IBinder onBind(Intent intent) {
return musicBind;
}
//release resources when unbind
@Override
public boolean onUnbind(Intent intent){
mediaPlayer.stop();
mediaPlayer.release();
return false;
}
//play a song
public void playSong(Uri songUri){
//play
mediaPlayer.reset();
//set the data source
try{
mediaPlayer.setDataSource(getApplicationContext(), songUri);
}
catch(Exception e){
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
mediaPlayer.prepareAsync();
MainActivity mainActivity = new MainActivity();
mainActivity.updateTimer();
}
public void setSong(Uri newSongUri) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
//getApplicationContext().startActivity(intent);
playSong(newSongUri);
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
}
@Override
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
return false;
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
//start playback
mediaPlayer.start();
}
private void runOnUiThread(Runnable runnable) {
handler.post(runnable);
}
public int getDuration(){
int duration = mediaPlayer.getDuration();
return duration;
}
public int getPosition(){
int position = mediaPlayer.getCurrentPosition();
return position;
}
}
Java堆栈跟踪:
12-31 15:52:40.088 28371-28371/com.bartkoppelmans.wavelength E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.bartkoppelmans.wavelength, PID: 28371
java.lang.NullPointerException
at android.app.Activity.findViewById(Activity.java:1965)
at com.bartkoppelmans.wavelength.MainActivity$4$1.run(MainActivity.java:161)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:3)
您无法在“活动与服务”之间进行通信
在MusicService
内:
MainActivity mainActivity = new MainActivity();
mainActivity.updateTimer();
您的空指针是因为当您说new MainActivity()
时,您创建的活动未附加到生命周期,因此onCreate
和其他方法未被调用,因此没有onCreate
表示否{ {1}}表示使用setContentView
找到的所有观看均为空
要在服务和活动之间进行通信,请使用以下方法之一:
http://www.vogella.com/tutorials/AndroidServices/article.html#servicecommunication
http://developer.android.com/guide/components/bound-services.html#Messenger
答案 1 :(得分:1)
使用您提供的信息进行调试真的非常困难。正如@duffymo所说,VM 总是正确。解决NPE的方法是查看堆栈跟踪,转到代码中的相应行,然后在该行上修改为null的变量。
在您的情况下,导致错误的原因是您在MainActivity
中创建的playSong
实例中没有根视图。 findViewById
期望安装的视图,并且当它为null时失败。
您可能无法创建活动的新实例并期望它们正常运行。只有框架才能做到这一点。您可能需要找到一种从MainAcitivity.onStart更新计时器的方法。