【问题标题】:Multiple Activities with one XML File一个 XML 文件的多个活动
【发布时间】:2017-01-08 14:01:35
【问题描述】:

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

  1. MainActivity.java(带有相应的 XML 文件:activity_main):此 Activity 有一个列表视图,显示所有可用歌曲的列表。

  2. PlayerScreen.java(带有相应的 XML 文件:activity_player_screen):当在第一个活动上单击一首歌曲时,该活动将启动并播放该特定歌曲。此活动有 3 个按钮(播放/暂停、下一首歌曲、上一首歌曲)和一个搜索栏。

现在这是我面临的问题

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

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

我认为我无法将 activity_player_screen 文件与 PlayerScreen.java 和 SeekBarThread.java 正确链接。

这是从 PlayerScreen.java 对 Thread 类的调用

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

我真的不知道摆脱异常,所以我将 seekbar 对象和 mediaplayer 对象引用以及当前上下文引用传递给 SeekBarThread 类。但它没有用。

这里是 SeekBarThread.java 类代码:

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 类:

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() 代码都根据用户从上一个活动中的选择来处理要播放的歌曲。而且由于这首歌正在播放,我认为这部分代码没有问题。

【问题讨论】:

    标签: android multithreading android-mediaplayer mediastore android-seekbar


    【解决方案1】:

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

    1) 不应在 run() 方法中的 SeekBarThread 类中设置 setContentView(),因为它已在活动类中设置,因为您没有重新初始化单击侦听器。

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

    3) 这里的重点是您在 MediaPlayer 初始化之前初始化 SeekBarThread 类,因此即使在寻找 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;
            }
        }
    }
    

    公共类 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();
            }
        }
    }
    

    }

    【讨论】:

    • 添加了 XML 文件
    • 您是否为活动类中的按钮添加了点击监听器?也发布您的活动课程
    • 添加了类代码。抱歉,我应该将它与原始帖子本身一起添加。
    • 尝试删除这一行 ((Activity)context).setContentView(R.layout.activity_player_screen);在你的可运行类中。
    • 因此您正在重置视图并且不向视图添加任何侦听器
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多