- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用媒体播放器从 url 流式传输 mp3 音频,现在我可以播放音乐,但是当我按下后退按钮或关闭应用程序时,它崩溃了。谁能帮我找出我的错误。谢谢。
我的代码是:
private ImageView play, forward, backward;
private MediaPlayer mediaPlayer;
private boolean playing = false;
private ProgressDialog dialog;
private String mp3link;
private SeekBar seekbar;
private Handler handler = new Handler();
private int mediaPos;
private int mediaMax;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String url ="";
initWidgets();
}
private void initWidgets() {
mp3link = "http://loc8app.com/church/uploads/audio/749928ad6fcb7b1aceefdf03bd7a9465.mp3";
play = (ImageView) findViewById(R.id.control);
seekbar = (SeekBar) findViewById(R.id.seekBar);
// forward = (ImageView) findViewById(R.id.playeer_forward);
// backward = (ImageView) findViewById(R.id.playeer_back);
mediaPlayer = new MediaPlayer();
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
playFunction();
}
});
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mediaPlayer != null && fromUser){
mediaPlayer.seekTo(progress);
}
}
});
}
private void playFunction() {
if (!playing) {
try {
dialog = ProgressDialog
.show(MainActivity.this,
"",
getString(com.root5solutions.music.R.string.buffering),
true);
dialog.setCancelable(true);
dialog.show();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(mp3link);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
play.setBackgroundResource(R.drawable.pause);
playing = true;
//this is new
mediaPos = mp.getCurrentPosition();
mediaMax = mp.getDuration();
seekbar.setMax(mediaMax);
seekbar.setProgress(mediaPos);
//this line is the error
handler.removeCallbacks(moveSeekBarThread);
handler.postDelayed(moveSeekBarThread, 100);
mp.start();
dialog.dismiss();
}
});
mediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
dialog.dismiss();
}
} else {
play.setBackgroundResource(R.drawable.play);
mediaPlayer.stop();
mediaPlayer.release();
playing = false;
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
private Runnable moveSeekBarThread = new Runnable() {
public void run() {
if (mediaPlayer.isPlaying()) {
int mediaPos_new = mediaPlayer.getCurrentPosition();
int mediaMax_new = mediaPlayer.getDuration();
seekbar.setMax(mediaMax_new);
seekbar.setProgress(mediaPos_new);
handler.postDelayed(this, 1000); // Looping the thread after 1 second
}
}
};
}
Logcat 显示:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.root.music, PID: 26981
java.lang.IllegalStateException
at android.media.MediaPlayer.isPlaying(Native Method)
at com.root.music.MainActivity$4.run(MainActivity.java:132)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5351)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:947)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:742)
最佳答案
问题似乎是由 moveSeekBarThread
引起的Runnable
,从中引发异常,在 mediaPlayer
之后继续执行在 onBackPressed()
中发布.这导致 isPlaying()
正在执行的方法,根据 documentation将导致 IllegalStateException
:
if the internal player engine has not been initialized or has been released.
查看moveSeekBarThread
, 它似乎被配置为通过将自己发布回 handler
来无休止地重新安排自己Handler
有延迟的例子。当用户离开 Activity 时,此过程不会停止,这解释了为什么 moveSeekBarThread
继续运行。因此,基于以上所述,一种解决方案可能是确保 moveSeekBarThread
的任何实例在 handler
的队列在调用 mediaPlayer.release()
之前被移除当用户离开 Activity 时。
您应该可以通过调用 handler.removeCallbacks(moveSeekBarThread);
来做到这一点在你打电话之前 mediaPlayer.release()
.例如如下:
@Override
public void onBackPressed() {
super.onBackPressed();
handler.removeCallbacks(moveSeekBarThread);
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
在mediaPlayer.release()
之前调用应该没问题, 但我认为无论 mediaPlayer
是否都调用它更安全正在玩。这样,如果 Runnable
尽管媒体播放器没有启动或停止,但确实以某种方式启动或保持启动状态,Runnable
仍将被清除。
顺便说一句,虽然我对 MediaPlayer
没有任何经验, 我碰巧注意到 release
的文档方法有如下说法:
It is considered good practice to call this method when you're done using the MediaPlayer. In particular, whenever an Activity of an application is paused (its onPause() method is called), or stopped (its onStop() method is called), this method should be invoked to release the MediaPlayer object, unless the application has a special need to keep the object around. In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a MediaPlayer object is no longer needed may also lead to continuous battery consumption for mobile devices, and playback failure for other applications if no multiple instances of the same codec are supported on a device.
因此,除非在您的情况下特别需要在 Activity 中保留媒体播放器,否则最好在 moveSeekBarThread
中处理发布过程(包括从 handler
中清除 onPause
)。或 onStop
相反。
希望对您有所帮助!
关于安卓媒体播放器 : IllegalStateException when app closes/press back button,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40603618/
似乎最近我看到越来越多的人开始在他们的样式表中使用 media="all" 而不是 media="screen"。 我的问题是什么时候应该使用 media="all" 而不是 media="scree
我正在尝试使用 https://www.instagram.com/developer/endpoints/media/ ,但对于我使用的每个媒体 ID,我总是得到相同的结果: { "meta
哟,我正在为服务器制作一个 MOTD 供最终用户阅读。但是,对于使用较小显示器的用户来说,它看起来非常压缩,例如,当分辨率为 1280x1040 时,它会被拉低。我不熟悉 CSS 中的 @media
我在我的 CSS 文件中使用了 @media screen 而不是 (-webkit-min-device-pixel-ratio:0)。我的问题是关于指定的值,即在这种情况下为“0”。值的变化将如何
我正在播放 Activity 中的视频,我需要显示/隐藏顶部栏 View 以及媒体 Controller 。所以当媒体 Controller 在屏幕上时,我的顶部 View 应该是可见的,当媒体 Co
我在我的 WordPress 主题中创建了一个小部件来显示图像。到目前为止,小部件可以工作,我可以输入值并在前端显示这些值。 当我选择一个小部件并将其放入小部件区域时,媒体上传按钮不起作用。在 Wor
我正在使用MWFeedParser从此处读取Youtube原子供稿:here xml代码: 我如何获取媒体的网址:缩略图? 我试图更改MWFeedParser.m 由此: else if ([cu
当使用 Python 向 Instagram API 发出 GET 请求时,传递所需的变量,如下所示 photos = api.media_search(lat=latitude, lng=longi
我正在使用与媒体播放器关联的媒体 Controller 来播放声音。问题是媒体 Controller 一旦失去焦点就会隐藏起来。我有一个按钮,按下时会播放声音,媒体 Controller 会出现在屏幕
我有一个媒体播放器并与它关联了一个媒体 Controller 。控件工作正常。 我遇到了两个问题: 当媒体 Controller 获得焦点时,即用户触摸它然后触摸屏幕的另一部分时,媒体 Control
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我在对话框中显示一个 VideoView 并向其附加一个媒体控件。 但是当我尝试点击媒体控件(播放、搜索栏等)时,对话框会消失。 媒体控制按钮不会被点击,而是将点击注册为 Dialog 的 Outsi
我目前正在使用 HTML 编写可打印文档,它将显示从数据库中提取的数据。我的想法是我将使用 HTML/CSS 使文档看起来不错,但它将专门用于打印。 文档的布局使用表格来控制数据库中数据的显示方式。
我需要在网络应用程序中打印我的报告。 我有在我的代码中。但它不应用任何样式。另一方面,如果我使用 在文档中编写 print.css 代码一切正常。 怎么了? 最佳答案 也许你在主样式之前插入打印样式
CSS html{ overflow-y:scroll; } js function showW(){ var a=($(window).width()); $('#
我编写了一个 Chrome 扩展程序,其中一个功能是您可以在您所在的页面中调出一个帮助面板,其中包含其使用指南。这个帮助面板是通过JS插入到页面中的,它的CSS都是通过$('#selector_for
我需要为 WORM 媒体开发归档软件。 这种类型的媒体允许通常的访问操作:读取、写入,但文件一旦写入,就无法修改或删除。 因为这样的媒体可能很昂贵,我想知道如何在开发阶段为测试创建一个假的 WORM
下面的这个 Activity 工作正常,但 mediaController 仅在我单击屏幕时显示。第二个问题是媒体 Controller 只显示 3 秒。我应该怎么做才能消除这个问题? public
我正在使用 VideoView 播放本地 mp4,我也在使用 MediaController。媒体控制栏未显示在我的视频剪辑下方,而是显示在屏幕中间。我使用 setAnchorView 将其附加到我的
我的布局包含 videoView 还有java代码中的Medicontrolleri: final MediaController mediaCont
我是一名优秀的程序员,十分优秀!