Reputation:
I've got a method inside my activity which is calling setText(), but it's returning a nullpointerexception on the textView. Can anyone tell me why?
See below for the snippets:
@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));
}
...
I need to keep the method displaySong as static, for various reasons, so I can't put the
songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel);
Inside the method.. AFAIK. Also, the nullpointerexception occurs at the line
songArtistAlbumLabel.setText((currentArtist) + " - " + (currentAlbum));
Inside the method.
Any advice is much appreciated.
--Edit--
Full code:
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
}
}
--Edit 2--
Added 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>
Upvotes: 0
Views: 1237
Reputation: 9753
nullpointerexception
is not the main problem here. The problem lays in your design.
You make the displaySong()
method static, I assume, to be able to call it from outside your activity. You use TextView songArtistAlbumLabel
in it, so you have to make it static as well. But it's a major flaw in design, since static fields do not belong to the class instance, they belong to the class. songArtistAlbumLabel
, however, should obviously belong to Activity instance. Here is a possible scenario - you call displaySong()
method, while Activity was never launched, so displaySong
is null
and you get npe
. Here is another possible scenario - you call displaySong()
after Activity was destroyed and songArtistAlbumLabel
is nowhere on the screen, but you are still trying to set a label for it.
There is a dirty hack - you can store reference to an instance of Activity in another static field with a public getter method (kinda like singleton), and refer to it in your static method to findViewById()
. But this does not make things any better.
Solution would be to use Intents to pass messages to activity from the outside and check for them in onCreate()
via getIntent()
method and listening to them in onNewIntent() method of your activity
EDIT if you are only going to call it from the service, check The Music Player
section in The Busy Coder's Guide to Android Development
Upvotes: 2
Reputation: 34071
Assuming you call displaySong()
after setting songArtistAlbumLabel
, the most likely explanation is that R.id.songArtistAlbumLabel
doesn't match any id in your layout.
Upvotes: 0