我创建了一个加载活动,该活动显示了从我自己的URL提取MP3文件时的加载GIF。当媒体播放器准备就绪时,我将其放入我的单例中,然后转到意图(以便我可以在此新活动中使用该MP3)。
事实是这种情况很少会发生,并且通常会长时间闲置(甚至都不会调用onListener)
请帮助。
package com.example.songguessapp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent; import android.media.AudioAttributes;
import android.media.MediaPlayer; import android.os.Bundle; import
android.util.Log; import android.view.View; import
android.widget.Toast;
import java.io.IOException;
public class LoadingActivity extends AppCompatActivity {
SongGame game;
static public MediaPlayer mpTemp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loading_screen);
game = SongGame.getInstance();
String songCode = String.valueOf(game.getRound() + 1);
String url = "https://mp3stream.herokuapp.com/code=song" + songCode ;
final MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build());
try {
mediaPlayer.setDataSource(url);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this,e.toString(),Toast.LENGTH_LONG).show();
}
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
Log.d("1001","Song downloaded");
toGameScreen(mp)
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d("1002","Error here");
return false;
}
});
}
public void toGameScreen(MediaPlayer mp) {
SongGame.getInstance().setMediaPlayer(mp);
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
}
}
编辑这是我的编辑版本(已完成),但我不知道线程问题与我以前的工作有何关系。
package com.example.songguessapp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.io.IOException;
public class LoadingActivity extends AppCompatActivity {
SongGame game;
public MediaPlayer mpTemp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loading_screen);
// final MediaPlayer mediaPlayer = new MediaPlayer();
// mediaPlayer.setAudioAttributes(
// new AudioAttributes
// .Builder()
// .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
// .build());
// try {
// mediaPlayer.setDataSource(url);
//
// } catch (IOException e) {
// e.printStackTrace();
// Toast.makeText(this,e.toString(),Toast.LENGTH_LONG).show();
// }
// mediaPlayer.prepareAsync();
//
// mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// @Override
// public void onPrepared(MediaPlayer mp) {
// toGameScreen(mp);
//
// }
// });
//
// mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
// @Override
// public boolean onError(MediaPlayer mp, int what, int extra) {
//
// return false;
// }
// });
new Thread(new Runnable() {
@Override
public void run() {
game = SongGame.getInstance();
String songCode = String.valueOf(game.getRound() + 1);
String url = "https://mp3stream.herokuapp.com/code=song" + songCode ;
final MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build());
try {
mediaPlayer.setDataSource(url);
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
toGameScreen(mediaPlayer)
}).start();
}
public void toGameScreen(MediaPlayer mp) {
SongGame.getInstance().setMediaPlayer(mp);
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
}
}
我对媒体播放没有经验,但是您使用线程的解决方案提醒我,在Android中,您必须总是尝试NOT阻止UI线程。通过此链接https://developer.android.com/guide/topics/media/mediaplayer主要文档:
使用MediaPlayer原则上可以很简单。但是,重要的是要记住,还需要做一些其他事情将其与典型的Android应用程序正确集成。对于例如,对prepare()的调用可能需要很长时间才能执行,因为它可能涉及获取和解码媒体数据。所以是这样对于任何可能需要很长时间才能执行的方法,您切勿从应用程序的UI线程调用它。 。 。 。至避免挂起您的UI线程,生成另一个线程进行准备MediaPlayer,并在完成后通知主线程。
所以,我的建议是尝试在前台服务https://developer.android.com/guide/components/services上运行播放>