0

我的活动中有一个调用 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>
4

2 回答 2

2

nullpointerexception不是这里的主要问题。问题在于你的设计。

我假设您将displaySong()方法设为静态,以便能够从您的活动之外调用它。您TextView songArtistAlbumLabel在其中使用它,因此您也必须使其成为静态的。但这是设计上的一个重大缺陷,因为静态字段不属于类实例,它们属于类。songArtistAlbumLabel但是,显然应该属于 Activity 实例。这是一个可能的场景 - 你调用displaySong()方法,而 Activity 从未启动,所以displaySongnull得到了npe. 这是另一种可能的情况 - 您displaySong()在 Activity 被销毁并且songArtistAlbumLabel屏幕上没有任何位置后调用,但您仍在尝试为其设置标签。

有一个肮脏的技巧 - 您可以使用公共 getter 方法(有点像单例)将 Activity 实例的引用存储在另一个静态字段中,并在您的静态方法中将其引用到findViewById(). 但这并没有让事情变得更好。

解决方案是使用IntentsonCreate()从外部将消息传递给活动,并通过方法检查它们并在活动的onNewIntent()方法中getIntent()收听它们

编辑如果您只打算从服务中调用它,请查看The Busy Coder's Guide to Android DevelopmentThe Music Player中的部分

于 2012-06-07T10:35:21.373 回答
0

假设您displaySong()在设置后调用songArtistAlbumLabel,最可能的解释是R.id.songArtistAlbumLabel与您布局中的任何 id 都不匹配。

于 2012-06-07T09:54:01.813 回答