我的活动中有一个调用setText()的方法,但它在textView上返回nullpointerexception。谁能告诉我为什么?
请参阅下面的摘要:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playing);
...
songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel);
...
static void displaySong(String currentArtist, String currentAlbum,
String currentTitle, String totalDuration, Uri currentSongUri) {
songArtistAlbumLabel.setText((currentArtist) + " - " + (currentAlbum));
}
...
由于各种原因,我需要将方法displaySong保持为静态,所以我不能把
songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel);
方法内..AFAIK。此外,nullpointerexception发生在
行songArtistAlbumLabel.setText((currentArtist) + " - " + (currentAlbum));
在方法内部。
非常感谢任何建议。
- 编辑 -
完整代码:
package awesome.music.player;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MusicPlayer extends Activity implements OnSeekBarChangeListener {
public ImageButton play;
public ImageButton next;
public ImageButton previous;
public static ImageView albumArt;
static TextView songArtistAlbumLabel;
static TextView songTitleLabel;
static TextView currentDurationLabel;
static TextView totalDurationLabel;
static String serviceStatus;
private SeekBar seekBar;
private int seekMax;
boolean mBroadcastIsRegistered;
public static Utilities utils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playing);
play = (ImageButton) findViewById(R.id.playButton);
next = (ImageButton) findViewById(R.id.nextButton);
previous = (ImageButton) findViewById(R.id.previousButton);
albumArt = (ImageView) findViewById(R.id.imageView1);
songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel);
play.setOnClickListener(playListener);
next.setOnClickListener(nextListener);
previous.setOnClickListener(previousListener);
seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(this);
intent = new Intent(BROADCAST_SEEKBAR);
if (mBroadcastIsRegistered != true) {
registerReceiver(broadcastReceiver, new IntentFilter(
MusicService.BROADCAST_ACTION));;
mBroadcastIsRegistered = true;
}
}
private OnClickListener playListener = new OnClickListener() {
public void onClick(View v) {
MusicService.playSong();
}
};
private OnClickListener nextListener = new OnClickListener() {
public void onClick(View v) {
MusicService.playNext();
}
};
private OnClickListener previousListener = new OnClickListener() {
public void onClick(View v) {
MusicService.playPrevious();
}
};
public static final String BROADCAST_SEEKBAR = "awesome.music.player.sendseekbar";
Intent intent;
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent serviceIntent) {
updateUI(serviceIntent);
}
};
static void displaySong(String currentArtist, String currentAlbum,
String currentTitle, String totalDuration, Uri currentSongUri) {
songArtistAlbumLabel.setText(currentArtist + " - " + currentAlbum);
songTitleLabel.setText(currentTitle);
totalDurationLabel.setText(totalDuration);
albumArt.setImageURI(currentSongUri);
}
private void updateUI(Intent serviceIntent) {
String counter = serviceIntent.getStringExtra("counter");
String mediamax = serviceIntent.getStringExtra("mediamax");
String strSongEnded = serviceIntent.getStringExtra("song_ended");
int seekProgress = Integer.parseInt(counter);
seekMax = Integer.parseInt(mediamax);
Integer.parseInt(strSongEnded);
seekBar.setMax(seekMax);
seekBar.setProgress(seekProgress);
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
int seekPos = seekBar.getProgress();
intent.putExtra("seekpos", seekPos);
sendBroadcast(intent);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
- 编辑2 -
添加了xml:
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SeekBar
android:id="@+id/seekBar"
android:layout_width="296dp"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_x="10dp"
android:layout_y="446dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:progressDrawable="@drawable/seekbar_progress"
android:thumb="@drawable/seek_handler" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="37dp"
android:layout_height="37dp"
android:layout_x="6dp"
android:layout_y="397dp"
android:src="@drawable/ic_tab_albums_white" />
<TextView
android:id="@+id/songTitleLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="55dp"
android:layout_y="395dp"
android:text="Song Label"
android:textSize="20sp" />
<TextView
android:id="@+id/songArtistAlbumLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="55dp"
android:layout_y="417dp"
android:text="Artist - Album Label"
android:textSize="15sp" />
<TextView
android:id="@+id/currentDurationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="10dp"
android:layout_y="481dp"
android:text="0:00" />
<TextView
android:id="@+id/totalDurationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="281dp"
android:layout_y="477dp"
android:text="3:30" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="41dp"
android:layout_y="312dp"
android:gravity="center_horizontal" >
<ImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="132dp"
android:layout_y="308dp"
android:src="@drawable/ic_previous" />
<ImageButton
android:id="@+id/playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50sp"
android:layout_marginRight="50sp"
android:src="@drawable/ic_pause" />
<ImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_next" />
</LinearLayout>
<ImageView
android:id="@+id/imageView1"
android:layout_width="287dp"
android:layout_height="272dp"
android:layout_x="16dp"
android:layout_y="13dp"
android:background="@drawable/dummy_album_art"
android:scaleType="fitXY" />
</AbsoluteLayout>
答案 0 :(得分:2)
nullpointerexception
不是这里的主要问题。问题在于你的设计。
我认为displaySong()
方法是静态的,可以从您的活动外部调用它。您在其中使用TextView songArtistAlbumLabel
,因此您也必须将其设为静态。但这是设计中的一个主要缺陷,因为静态字段不属于类实例,它们属于类。但是,songArtistAlbumLabel
显然属于Activity实例。这是一种可能的方案 - 您调用displaySong()
方法,而活动从未启动,因此displaySong
为null
,您获得npe
。这是另一种可能的情况 - 您在活动被销毁后调用displaySong()
并且屏幕上没有songArtistAlbumLabel
,但您仍在尝试为其设置标签。
有一个肮脏的黑客 - 您可以使用公共getter方法(有点像singleton)在另一个静态字段中存储对Activity实例的引用,并在静态方法中将其引用到findViewById()
。但这并没有让事情变得更好。
解决方案是使用Intents从外部将消息传递给活动,并通过onCreate()
方法在getIntent()
方法中检查这些消息,并在onNewIntent()方法中查看它们你的活动
编辑如果您只是要从服务中拨打电话,请查看The Busy Coder's Guide to Android Development中的The Music Player
部分
答案 1 :(得分:0)
假设您在设置displaySong()
后致电songArtistAlbumLabel
,最可能的解释是R.id.songArtistAlbumLabel
与您布局中的任何ID都不匹配。