一个 XML 文件的多项活动

Multiple Activities with one XML File

我正在 android 中制作音乐播放器应用程序。该应用程序有

  1. MainActivity.java(对应XMLFile:activity_main):这个Activity有一个列表视图,显示所有可用歌曲的列表。

  2. PlayerScreen.java(对应XMLFile:activity_player_screen):当一首歌曲点击第一个activity,这个activity启动并播放该特定歌曲。这个 activity 有 3 个按钮(Play/Pause、NextSong、PreviousSong)和一个搜索栏。

这就是我面临的问题

我创建了一个单独的 class (SeekBarThread.java) 用于使用线程实现 activity_player_screen 的搜索栏。

问题是,当我从 PlayerScreen.java 调用我的线程 class 的启动方法时,没有任何反应。不会抛出异常。歌曲继续播放,但 activity_player_screen 的小部件停止工作,即我无法暂停歌曲或播放下一首歌曲。搜索栏也不起作用。

我想我无法 link 包含 PlayerScreen.java 和 SeekBarThread.java 的 activity_player_screen 文件。

这是 PlayerScreen.java

对线程 class 的调用
mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
myThread = new Thread(mySeekBarThread);
myThread.start();

我真的没有摆脱异常的想法,所以我将 seekbar 对象和 mediaplayer 对象引用以及当前上下文引用传递给了 SeekBarThread class。但是没用。

这里是 SeekBarThread.java class 代码:

public class SeekBarThread implements Runnable{

private PlayerScreen myPlayerScreen;
private SeekBar seekBar;
private MediaPlayer mp;
private Context context;

public SeekBarThread(Context context, SeekBar seekBar, MediaPlayer mp) {
    this.context = context;
    this.seekBar = seekBar;
    this.mp = mp;
}

public void run() {

    ((Activity)context).setContentView(R.layout.activity_player_screen);
    seekBar.setMax(mp.getDuration());

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mp.seekTo(seekBar.getProgress());
        }
    });

    int totalduration = mp.getDuration();
    int currentposition = 0;
    while(currentposition < totalduration) {
        try {
            sleep(500);
            currentposition = mp.getCurrentPosition();
            seekBar.setProgress(currentposition);
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}
}

activity_player_screen XML 文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_player_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="prakhar.simplemusicplayer20.PlayerScreen">

<Button
    android:id="@+id/play_pause"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:layout_alignParentBottom="true"
    android:layout_centerInParent="true"
    android:background="@drawable/pause" />

<Button
    android:id="@+id/next_song"
    android:layout_height="42dp"
    android:layout_width="42dp"
    android:background="@drawable/next"
    android:layout_marginEnd="25dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true" />

<Button
    android:id="@+id/prev_song"
    android:layout_height="42dp"
    android:layout_width="42dp"
    android:background="@drawable/previous"
    android:layout_marginStart="25dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true" />

<Button
    android:text="F"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:id="@+id/forward_song"
    android:layout_alignParentBottom="true"
    android:layout_toStartOf="@+id/next_song"
    android:layout_marginEnd="22dp" />

<Button
    android:text="R"
    android:layout_width="42dp"
    android:layout_height="42dp"
    android:id="@+id/rewind_song"
    android:layout_marginEnd="23dp"
    android:layout_alignParentBottom="true"
    android:layout_toStartOf="@+id/play_pause" />

<SeekBar
    android:id="@+id/seek_bar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_marginBottom="26dp"
    android:layout_above="@+id/play_pause"
    android:layout_alignParentStart="true" />

<TextView
    android:text="TextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="146dp"
    android:id="@+id/details_text_view" />


</RelativeLayout>

这里是 PlayerScreen.java class:

public class PlayerScreen extends AppCompatActivity implements     View.OnClickListener{

private Button playPause, nextSong, prevSong;
public SeekBar mySeekBar;
private int count = 0;
public MediaPlayer mediaPlayer;
private Bundle newBundle = new Bundle();
private Intent newIntent;
private int pos;
private ArrayList<String> name;
private ArrayList<String> path;
private SeekBarThread mySeekBarThread;
private Thread myThread;
private TextView detailsTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_player_screen);

    playPause = (Button)findViewById(R.id.play_pause);
    nextSong = (Button)findViewById(R.id.next_song);
    prevSong = (Button)findViewById(R.id.prev_song);
    mySeekBar = (SeekBar)findViewById(R.id.seek_bar);
    detailsTextView = (TextView)findViewById(R.id.details_text_view);

    playPause.setOnClickListener(this);
    nextSong.setOnClickListener(this);
    prevSong.setOnClickListener(this);

    newIntent = this.getIntent();
    newBundle = newIntent.getExtras();

    name = newBundle.getStringArrayList("title");
    path = newBundle.getStringArrayList("songpath");
    pos = newBundle.getInt("post");

    detailsTextView.setText(name.get(pos));

    mediaPlayer = new MediaPlayer();
    setMediaPlayer(pos);
}

public void setMediaPlayer(int position) {
    mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
    myThread = new Thread(mySeekBarThread);
    myThread.start();

    File mySong = new File(path.get(pos));
    mediaPlayer = new MediaPlayer();
    FileInputStream is = null;
    try {
        is = new FileInputStream(mySong);
    }
    catch(FileNotFoundException ex) {
        ex.printStackTrace();
    }

    try {
        mediaPlayer.setDataSource(is.getFD());
    }
    catch(IOException ex) {
        ex.printStackTrace();
    }

    try {
        mediaPlayer.prepare();
    }
    catch(IOException ex) {
        ex.printStackTrace();
    }
    finally {
        if(is != null) {
            try {
                is.close();
            }
            catch(IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    mediaPlayer.start();
}

@Override
protected void onPause() {
    super.onPause();
    mediaPlayer.pause();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mediaPlayer.stop();
}

@Override
public void onClick(View v) {
    switch(v.getId()) {
        case R.id.play_pause:
            count++;
            if(count%2 == 0) {
                v.setBackgroundResource(R.drawable.pause);
                mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
                mediaPlayer.start();
            }
            else {
                v.setBackgroundResource(R.drawable.play);
                mediaPlayer.pause();
            }
            break;

        case R.id.next_song:
            mediaPlayer.stop();
            pos = pos + 1;
            setMediaPlayer(pos);
            break;

        case R.id.prev_song:
            mediaPlayer.stop();
            pos = pos - 1;
            setMediaPlayer(pos);
            break;
    }
}
}

大部分的 onCreate() 代码是 class 处理根据用户在之前 activity 中的选择播放哪首歌。由于正在播放这首歌,我认为那部分代码没有问题。

@prakhar,通过代码,我发现了以下问题:

1) 在 SeekBarThread class 中 运行() 方法 setContentView() 不应该设置,因为它已经在 activity class 中设置,因为你不会重新初始化点击侦听器。

2) 此外,seekbarchangeListener 不应在 运行() 方法中设置,而应在主 activity 本身中设置,因为它不需要一直重新初始化。

3) 这里的重点是你在初始化 MediaPlayer 之前初始化了 SeekBarThread class,因此即使在搜索 seekbar 之后也没有任何动作。

修正了上述修改的详细代码。

public class PlayerScreen extends AppCompatActivity implements View.OnClickListener {

    private Button playPause, nextSong, prevSong;
    public SeekBar mySeekBar;
    private int count = 0;
    public MediaPlayer mediaPlayer;
    private Bundle newBundle = new Bundle();
    private Intent newIntent;
    private int pos;
    private ArrayList<String> name;
    private ArrayList<String> path;
    private SeekBarThread mySeekBarThread;
    private Thread myThread;
    private TextView detailsTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        playPause = (Button) findViewById(R.id.play_pause);
        nextSong = (Button) findViewById(R.id.next_song);
        prevSong = (Button) findViewById(R.id.prev_song);
        mySeekBar = (SeekBar) findViewById(R.id.seek_bar);
        detailsTextView = (TextView) findViewById(R.id.details_text_view);

        playPause.setOnClickListener(this);
        nextSong.setOnClickListener(this);
        prevSong.setOnClickListener(this);

        mySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mediaPlayer.seekTo(seekBar.getProgress());
            }
        });

        newIntent = this.getIntent();
        newBundle = newIntent.getExtras();

        name = newBundle.getStringArrayList("title");
        pos = newBundle.getInt("post");

        detailsTextView.setText(name.get(pos));

        mediaPlayer = new MediaPlayer();
        setMediaPlayer(pos);
    }

    public void setMediaPlayer(int position) {

        File mySong = new File(path.get(pos));
        mediaPlayer = new MediaPlayer();
        FileInputStream is = null;
        try {
            is = new FileInputStream(mySong);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }

        try {
            mediaPlayer.setDataSource(is.getFD());
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        try {
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.prepare();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        mediaPlayer.start();

        mySeekBarThread = new SeekBarThread(this, mySeekBar, mediaPlayer);
        myThread = new Thread(mySeekBarThread);
        myThread.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mediaPlayer.pause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.play_pause:
                count++;
                if (count % 2 == 0) {
                    v.setBackgroundResource(R.drawable.pause);
                    mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
                    mediaPlayer.start();
                } else {
                    v.setBackgroundResource(R.drawable.play);
                    mediaPlayer.pause();
                }
                break;

            case R.id.next_song:
                mediaPlayer.stop();
                pos = pos + 1;
                setMediaPlayer(pos);
                break;

            case R.id.prev_song:
                mediaPlayer.stop();
                pos = pos - 1;
                setMediaPlayer(pos);
                break;
        }
    }
}

public class SeekBarThread 实现 Runnable{

private SeekBar seekBar;
private MediaPlayer mp;
private Context context;

public SeekBarThread(Context context, SeekBar seekBar, MediaPlayer mp) {
    this.context = context;
    this.seekBar = seekBar;
    this.mp = mp;
}

public void run() {

    seekBar.setMax(mp.getDuration());



    int totalduration = mp.getDuration();
    int currentposition = 0;
    while(currentposition < totalduration) {
        try {
            sleep(500);
            currentposition = mp.getCurrentPosition();
            seekBar.setProgress(currentposition);
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

}