- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究绑定(bind)服务、前台服务以及如何使用它们进行音频播放。
基于this example我已经设置了一个前台服务来播放音频。这非常适合我的用例,直到我尝试绑定(bind)服务,因为我需要在 Activity 和服务之间来回传递一些数据,例如我想要实现的搜索栏的播放位置。
我浏览了几篇 StackOverflow 帖子,试图找到解决方案。我知道我应该在启动服务之前绑定(bind)该服务,这样它就不会与它所绑定(bind)的 Activity 一起被杀死。但一旦我添加了绑定(bind)机制,这仍然会发生。
当我将设备置于 sleep 状态时,这是我在 logcat 中看到的唯一错误:
2019-11-12 10:49:24.553 812-871/? W/InputDispatcher: channel '7fc2cb2 com.example.android.meditationhub/com.example.android.meditationhub.ui.PlayActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x9
2019-11-12 10:49:24.553 812-871/? E/InputDispatcher: channel '7fc2cb2 com.example.android.meditationhub/com.example.android.meditationhub.ui.PlayActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
所以,我需要找出 channel 被破坏的原因,但目前我很困惑还能去哪里寻找。 ...
这是我当前的 PlayActivity 设置:
//called from onCreate()
private void initializeUI() {
playerBinding.playbackControlBt.setPlayListener(new AnimatePlayButton.OnButtonsListener() {
@Override
public boolean onPlayClick(View view) {
mediaPlayerServiceInt = new Intent(PlayActivity.this, MediaPlayerService.class);
mediaPlayerServiceInt.setAction(Constants.START_ACTION);
mediaPlayerServiceInt.putExtra(Constants.URI, medUri);
startService(mediaPlayerServiceInt);
bindMediaPlayerService();
return true;
}
@Override
public boolean onPauseClick(View view) {
Intent pausePlayback = new Intent(PlayActivity.this, MediaPlayerService.class);
pausePlayback.setAction(Constants.PAUSE_ACTION);
PendingIntent pendingPausePlayback = PendingIntent.getService(PlayActivity.this,
0, pausePlayback, PendingIntent.FLAG_UPDATE_CURRENT);
try {
pendingPausePlayback.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
return true;
}
@Override
public boolean onResumeClick(View view) {
Intent resumePlayback = new Intent(PlayActivity.this, MediaPlayerService.class);
resumePlayback.setAction(Constants.PLAY_ACTION);
PendingIntent pendingResumePlayback = PendingIntent.getService(PlayActivity.this,
0, resumePlayback, PendingIntent.FLAG_UPDATE_CURRENT);
try {
pendingResumePlayback.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
return true;
}
@Override
public boolean onStopClick(View view) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
stopService(mediaPlayerServiceInt);
}
return true;
}
});
}
//monitor state of the service
private ServiceConnection mediaPlayerConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mediaPlayerService = ((MediaPlayerService.MyBinder) service).getService();
serviceIsBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
mediaPlayerService = null;
serviceIsBound = false;
}
};
//unbind service so the audio continues to play
private void unbindMediaPlayerService() {
unbindService(mediaPlayerConnection);
serviceIsBound = false;
Timber.v("Service unbound");
}
//bind service so the display can follow the audio playback
private void bindMediaPlayerService() {
if (!serviceIsBound) {
Intent bindInt = new Intent(this, MediaPlayerService.class);
serviceIsBound = bindService(bindInt, mediaPlayerConnection, Context.BIND_AUTO_CREATE);
Timber.v("Service bound");
} else {
Timber.v("no Service to bind");
}
}
@Override
protected void onStart() {
super.onStart();
if (MediaPlayerService.getState() != Constants.STATE_NOT_INIT) {
bindMediaPlayerService();
}
@Override
protected void onStop() {
super.onStop();
if (MediaPlayerService.getState() != Constants.STATE_NOT_INIT) {
unbindMediaPlayerService();
}
}
}
// Binder given to Activity
private final IBinder binder = new MyBinder();
/**
* Class used for the client Binder. The Binder object is responsible for returning an instance
* of {@link MediaPlayerService} to the client.
*/
public class MyBinder extends Binder {
public MediaPlayerService getService() {
// Return this instance of MyService so clients can call public methods
return MediaPlayerService.this;
}
}
@Override
public IBinder onBind(Intent arg0) {
return binder;
}
@Override
public void onCreate() {
super.onCreate();
(…)
stateService = Constants.STATE_NOT_INIT;
notMan = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
if (intent == null || intent.getAction() == null) {
stopForeground(true);
stopSelf();
return START_NOT_STICKY;
}
switch (intent.getAction()) {
case Constants.START_ACTION:
if(intent.getExtras() != null) {
medUri = (Uri) intent.getExtras().get(Constants.URI);
}
stateService = Constants.STATE_PREPARE;
startForeground(Constants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification());
destroyPlayer();
initPlayer();
play();
break;
case Constants.PAUSE_ACTION:
stateService = Constants.STATE_PAUSE;
notMan.notify(Constants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification());
destroyPlayer();
handler.postDelayed(delayedShutdown, Constants.DELAY_SHUTDOWN_FOREGROUND_SERVICE);
break;
case Constants.PLAY_ACTION:
stateService = Constants.STATE_PREPARE;
notMan.notify(Constants.NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification());
destroyPlayer();
initPlayer();
play();
break;
case Constants.STOP_ACTION:
Timber.i("Received Stop Intent");
destroyPlayer();
stopForeground(true);
stopSelf();
break;
default:
stopForeground(true);
stopSelf();
}
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
Timber.d("onDestroy()");
destroyPlayer();
stateService = Constants.STATE_NOT_INIT;
try {
timerUpdateHandler.removeCallbacksAndMessages(null);
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy();
}
您可以在 GitHub 上找到链接的完整代码。
目的是允许用户在收听时将设备置于 sleep 状态,或者让它自行进入休眠状态。服务的绑定(bind)是必要的,以便在设备打开或 Activity 进入前台时显示播放进度(通过搜索栏和计数器)。
我哪里出错了或者我忽略了什么?或者我应该考虑更好的方法?预先感谢您的任何指示和帮助。
预计到达时间:我已切换到未过滤的 logCat 并发现了一个新错误。我将开始粘贴保存外状态且未绑定(bind)服务的位置。
2019-11-14 09:57:42.942 8326-8326/com.example.android.meditationhub V/PlayActivity: all outstates saved
2019-11-14 09:57:42.943 8326-8326/com.example.android.meditationhub V/PlayActivity: all outstates saved
2019-11-14 09:57:42.944 8326-8326/com.example.android.meditationhub V/PlayActivity: all outstates saved
2019-11-14 09:57:42.950 8326-8326/com.example.android.meditationhub V/PlayActivity: Service unbound
2019-11-14 09:57:42.951 8326-8326/com.example.android.meditationhub V/PlayActivity: Service unbound
2019-11-14 09:57:42.953 225-1957/? I/BufferQueueProducer: [ColorFade](this:0xaab2a000,id:5867,api:1,p:812,c:225) new GraphicBuffer needed
2019-11-14 09:57:42.954 225-1957/? I/[MALI][Gralloc]: usage1: 0xf02, format: 1 stride: 720 vertical_stride: 1280 size: 3686400
2019-11-14 09:57:42.954 8326-8326/com.example.android.meditationhub V/PlayActivity: Service unbound
2019-11-14 09:57:42.955 225-1957/? D/GraphicBuffer: alloc, handle(0xac1921e0) (w:720 h:1280 s:720 f:0x1 u:0x000f02) err(0)
2019-11-14 09:57:42.958 812-859/? D/GraphicBuffer: register, handle(0x88e7d160) (w:720 h:1280 s:720 f:0x1 u:0x000f02)
2019-11-14 09:57:42.979 225-369/? I/BufferQueueProducer: [ColorFade](this:0xaab2a000,id:5867,api:1,p:812,c:225) new GraphicBuffer needed
2019-11-14 09:57:42.979 225-369/? I/[MALI][Gralloc]: usage1: 0xf02, format: 1 stride: 720 vertical_stride: 1280 size: 3686400
2019-11-14 09:57:42.980 225-369/? D/GraphicBuffer: alloc, handle(0xac1922a0) (w:720 h:1280 s:720 f:0x1 u:0x000f02) err(0)
2019-11-14 09:57:42.983 812-859/? D/GraphicBuffer: register, handle(0x88e789a0) (w:720 h:1280 s:720 f:0x1 u:0x000f02)
2019-11-14 09:57:42.994 812-3148/? D/PowerManagerNotifier: onWakeLockReleased: flags=1, tag="ActivityManager-Sleep", packageName=android, ownerUid=1000, ownerPid=812, workSource=null
2019-11-14 09:57:42.995 258-748/? D/Sunwave: sw_sensor 896:send cancel sem
2019-11-14 09:57:42.995 258-747/? I/Sunwave: sw-hal 281:irq canceled!
2019-11-14 09:57:42.995 258-747/? D/Sunwave: IC8221 1237:wait irq cancel
2019-11-14 09:57:42.995 258-747/? D/Sunwave: IC8221 712:soft reset
2019-11-14 09:57:42.998 258-733/? D/Sunwave: sw_sensor 225:irq receive wake, but g_bIrqEnable = 0
2019-11-14 09:57:43.000 258-747/? D/Sunwave: IC8221 2573:warning: fp irq canceled
2019-11-14 09:57:43.005 258-747/? D/Sunwave: FpFinger 2405:keyFinger cancel:1
2019-11-14 09:57:43.006 812-859/? D/DisplayPowerController: ABC configure: enabledInDoze=false, lowDimmingProtectionEnabled=false, adjustment=0.7919922, state=2, brightness=-1
2019-11-14 09:57:43.006 812-859/? D/AutomaticBrightnessController: getAutomaticScreenBrightness: brightness=255, dozing=false, factor=1.0
2019-11-14 09:57:43.007 812-859/? D/DisplayPowerController: Unfinished business...
2019-11-14 09:57:43.023 8326-8849/com.example.android.meditationhub D/FA: Logging event (FE): user_engagement(_e), Bundle[{ga_event_origin(_o)=auto, engagement_time_msec(_et)=5780, ga_screen_class(_sc)=PlayActivity, ga_screen_id(_si)=7992583200822585152}]
2019-11-14 09:57:43.024 8326-8326/com.example.android.meditationhub E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 895384)
2019-11-14 09:57:43.025 8326-8326/com.example.android.meditationhub D/AndroidRuntime: Shutting down VM
2019-11-14 09:57:43.026 943-943/? D/SystemServicesProxy: getTopMostTask: tasks: 2600
--------- beginning of crash
2019-11-14 09:57:43.027 8326-8326/com.example.android.meditationhub E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.meditationhub, PID: 8326
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 895384 bytes
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3865)
at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
Caused by: android.os.TransactionTooLargeException: data parcel size 895384 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:622)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3708)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3857)
at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
2019-11-14 09:57:43.034 812-1424/? W/ActivityManager: Force finishing activity com.example.android.meditationhub/.ui.PlayActivity
“交易太大”似乎是关键,但我对什么交易感到困惑。因为我还没有在服务和 Activity 之间进行沟通。我开始怀疑服务中的timerUpdateHandler
。当设备进入休眠状态时,我是否也应该停止通知?
最佳答案
问题不在于服务绑定(bind),而在于 OnSavedInstanceState
,它触发了 TansactionTooLargeException
。我将在这里提供我的解决方案,因为我怀疑其他人也可能遇到这个问题。
我需要重新训练 Activity 的任何数据都会传达给服务。服务立即需要的内容通过启动它的 Intent 传递。就我而言,这是音频 Uri 和标题。
mediaPlayerServiceInt = new Intent(PlayActivity.this, MediaPlayerService.class);
mediaPlayerServiceInt.setAction(Constants.START_ACTION);
mediaPlayerServiceInt.putExtra(Constants.URI, medUri);
mediaPlayerServiceInt.putExtra(Constants.TITLE, selectedMed.getTitle());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(mediaPlayerServiceInt);
} else {
startService(mediaPlayerServiceInt);
}
bindMediaPlayerService();
当我解除绑定(bind)时, Activity 需要在 UI 中显示的任何其他数据都会传递给服务。在我的例子中,coverArt 和所选对象 (selectedMed) 包含要显示的更多信息。
//unbind service so the audio continues to play
private void unbindMediaPlayerService() {
mediaPlayerService.setCoverArt(coverArt);
mediaPlayerService.setSelectedMed(selectedMed);
unbindService(mediaPlayerConnection);
serviceIsBound = false;
Log.v(TAG, "Service unbound");
}
非常感谢@greeble31,您回顾了所有可能性和尝试,帮助我将问题归结为根本原因!
关于java - 通过绑定(bind)的前台服务保持音频播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58816713/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!