问题分析

报错log信息如下

09-28 13:06:08.697706 30214 30214 E AndroidRuntime: FATAL EXCEPTION: main
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: Process: com.android.music, PID: 30214
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: java.lang.RuntimeException: Unable to create service com.android.music.MediaPlaybackService: java.lang.NullPointerException: Attempt to invoke interface method 'android.media.session.ISessionController android.media.session.ISession.getController()' on a null object reference
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.app.ActivityThread.handleCreateService(ActivityThread.java:4264)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.app.ActivityThread.access$1700(ActivityThread.java:244)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1995)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.os.Looper.loop(Looper.java:223)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7740)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.media.session.ISessionController android.media.session.ISession.getController()' on a null object reference
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.media.session.MediaSession.<init>(MediaSession.java:199)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.media.session.MediaSession.<init>(MediaSession.java:156)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at com.android.music.MediaPlaybackService.onCreate(MediaPlaybackService.java:45)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: at android.app.ActivityThread.handleCreateService(ActivityThread.java:4252)
09-28 13:06:08.697706 30214 30214 E AndroidRuntime: ... 8 more

从报错的log中和截图中看应该是打开蓝牙的时候会触发打开 Android Open Source Music Playback Service,从而导致的报错

<service android:name="com.android.music.MediaPlaybackService"android:exported="true"android:label="Android Open Source Music Playback Service"><intent-filter><action android:name="android.media.browse.MediaBrowserService" /></intent-filter>
</service>

packages/apps/Music/src/com/android/music/MediaPlaybackService.java

mSession = new MediaSession(this, "MediaPlaybackService");

frameworks/base/media/java/android/media/session/MediaSession.java

try {mBinder = manager.createSession(mCbStub, tag, sessionInfo);             mSessionToken = new Token(Process.myUid(), mBinder.getController());    // mBinder为空导致的报错,说明上面createSession没有成功mController = new MediaController(context, mSessionToken);
} catch (RemoteException e) {throw new RuntimeException("Remote error creating session.", e);
}

为什么 createSession 没有成功? 因为创建了太多的session了,导致报错,和问题中的描述一致
frameworks/base/services/core/java/com/android/server/media/MediaSessionService.java

@Override
public ISession createSession(String packageName, ISessionCallback cb, String tag,Bundle sessionInfo, int userId) throws RemoteException {final int pid = Binder.getCallingPid();final int uid = Binder.getCallingUid();final long token = Binder.clearCallingIdentity();try {enforcePackageName(packageName, uid);int resolvedUserId = ActivityManager.handleIncomingUser(pid, uid, userId,false /* allowAll */, true /* requireFull */, "createSession", packageName);if (cb == null) {throw new IllegalArgumentException("Controller callback cannot be null");}MediaSessionRecord session = createSessionInternal(pid, uid, resolvedUserId, packageName, cb, tag, sessionInfo);if (session == null) {throw new IllegalStateException("Failed to create a new session record");}ISession sessionBinder = session.getSessionBinder();if (sessionBinder == null) {throw new IllegalStateException("Invalid session record");}return sessionBinder;} catch (Exception e) {Slog.w(TAG, "Exception in creating a new session", e);              //通过这行log在sys_log中找到了关键信息throw e;} finally {Binder.restoreCallingIdentity(token);}
}

mobilelog/APLog_2021_0103_082059__1/sys_log_105__2021_0929_022307

09-28 18:45:47.365026   745  3090 W MediaSessionService: Exception in creating a new session
09-28 18:45:47.365026   745  3090 W MediaSessionService: java.lang.RuntimeException: Created too many sessions. count=100)      //创建了太多的session了,导致报错,和问题中的描述一致
09-28 18:45:47.365026   745  3090 W MediaSessionService: at com.android.server.media.MediaSessionService.createSessionInternal(MediaSessionService.java:601)
09-28 18:45:47.365026   745  3090 W MediaSessionService: at com.android.server.media.MediaSessionService.access$2400(MediaSessionService.java:105)
09-28 18:45:47.365026   745  3090 W MediaSessionService: at com.android.server.media.MediaSessionService$SessionManagerImpl.createSession(MediaSessionService.java:1144)
09-28 18:45:47.365026   745  3090 W MediaSessionService: at android.media.session.ISessionManager$Stub.onTransact(ISessionManager.java:289)
09-28 18:45:47.365026   745  3090 W MediaSessionService: at android.os.Binder.execTransactInternal(Binder.java:1154)
09-28 18:45:47.365026   745  3090 W MediaSessionService: at android.os.Binder.execTransact(Binder.java:1123)
09-28 18:45:47.411609   745   791 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: TURNING_ON > ON
09-28 18:45:47.412572   745   791 D BluetoothManagerService: Broadcasting onBluetoothStateChange(true) to 24 receivers.
09-28 18:45:47.419077   745   791 D BluetoothManagerService: Creating new ProfileServiceConnections object for profile: 1

然后找到下面这段代码,目前肯定是满足了第一个条件,private static final int SESSION_CREATION_LIMIT_PER_UID = 100;

if (sessionCount >= SESSION_CREATION_LIMIT_PER_UID&& !hasMediaControlPermission(callerPid, callerUid)) {throw new RuntimeException("Created too many sessions. count="+ sessionCount + ")");
}private boolean hasMediaControlPermission(int pid, int uid) {// Check if it's system server or has MEDIA_CONTENT_CONTROL.// Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra// check here.if (uid == Process.SYSTEM_UID || mContext.checkPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL, pid, uid)== PackageManager.PERMISSION_GRANTED) {return true;} else if (DEBUG) {Log.d(TAG, "uid(" + uid + ") hasn't granted MEDIA_CONTENT_CONTROL");}return false;
}

要满足第二个条件hasMediaControlPermission(),只有sharedUserId=system(platform签名),或者有media_content_control权限的应用才可以,尝试了给 Music 添加media_content_control权限无果,不知道问题出在哪里,有兴趣的朋友可以自己尝试一下

最终修改方案

1.不预置music应用
2.或给Music应用添加platform的签名
packages/apps/Music/Android.bp

android_app {name: "Music",srcs: ["src/**/*.java"],sdk_version: "current",product_specific: true,certificate: "platform",// 添加platform签名optimize: {proguard_flags_files: ["proguard.flags"],},
}

测试方法

1.修改 MediaSessionService.java 中的 SESSION_CREATION_LIMIT_PER_UID = 5; //可以减少测试次数
2.在 final int sessionCount = user.mUidToSessionCount.get(callerUid, 0); 后面添加如下log

android.util.Log.e(TAG, "Time:2021-10-14 15:44:03-->"+Thread.currentThread().getStackTrace()[2].getClassName()+"-->"+Thread.currentThread().getStackTrace()[2].getMethodName()+"()-->"+Thread.currentThread().getStackTrace()[2].getLineNumber()+" sessionCount:"+sessionCount+" hasMediaControlPermission:"+hasMediaControlPermission);

3.运行自己写的脚本 runTest bt

echo "run BT test begin!"
for (( i = 0; i < 10000; i++ )); doadb shell svc bluetooth enableecho "enable bluetooth for $i times!"sleep 2adb shell svc bluetooth disableecho "disable bluetooth for $i times!"sleep 2
done
echo "run BT test end!"

有几个疑问

1.为什么打开关闭蓝牙的时候没有关闭session?如何关闭session?
2.为什么google的Music不会有这个问题?
3.SESSION_CREATION_LIMIT_PER_UID = 100; 这个值是否可以改大?
4.有权限之后,session可以无限创建吗?会不会OOM或者且他问题?

欢迎大家一起学习讨论~~

Android压力测试不停开启关闭蓝牙报错相关推荐

  1. android 轨迹球事件,Android压力测试

    原标题:Android压力测试 来源:http://www.uml.org.cn 准备测试环境 准备Android SDK环境 下载 AndroidSDK 准备python环境 下载python AP ...

  2. mysql查询新建查询报错_mysql开启慢查询报错:

    1.进入mysql命令行:#mysql -uroot -p123456,执行下面的命令开启慢查询报错: set global slow_query_log=on; set global long_qu ...

  3. Android P使用pm install安装apk报错

    Android P使用pm install安装apk报错 avc: denied { read } for scontext=u:r:system_server:s0 tcontext=u:objec ...

  4. PostMan测试接口,出现415报错,Unsupported Media Type

    PostMan测试接口,出现415报错,Unsupported Media Type 问题描述: ​ 当用PostMan测试接口时候,出现如下报错 解决方法: ​ 打开返回信息中的Header条框,查 ...

  5. 关闭Tomcat报错appears to have started a thread named [Abandoned connection-cleanup] but has failed to st

    关闭Tomcat报错The web application [my_login] appears to have started a thread named [mysql-cj-abandoned- ...

  6. Android Studio 升级 gradle:3.6.0 报错:Entry name 'xxx-xxx.xml' collided

    Android Studio 升级 gradle:3.6.0 报错:Entry name 'xxx-xxx.xml' collided 删除掉目录中所有的build文件夹,重新Sync编译

  7. Android Notification通知RemoteView布局使用ConstraintLayout报错

    Android Notification通知RemoteView布局使用ConstraintLayout报错:inflate error ? Notification的自定义布局是RemoteView ...

  8. android服务器压力测试,Android压力测试Monkey工具

    最近在Android程序测试过程中接触到了自动化测试方法,对其中的一些工具.方法和框架做了一些简单的整理,其中包括android测试框架.CTS.Monkey.Monkeyrunner其它test t ...

  9. Android 10.0默认开启(关闭)移动数据流量

    1.概述 在10.0定制化开发中,互联网网络要么使用wifi要么是数据流量来进行上网,所以对于默认关闭数据流量的功能,也不难实现,找到相应的代码流程,修改默认值就可以了 2.默认开启(关闭)移动数据流 ...

最新文章

  1. 为什么 Pi 会出现在正态分布的方程中?
  2. [Elasticsearch] 部分匹配 (三) - 查询期间的即时搜索
  3. centOS7挂在windows移动硬盘方法
  4. 我的世界怎么设置服务器维护中,我的世界服务器
  5. winform调用SSH2访问linux,使用Cygwin通过ssh命令行来访问Windows 7
  6. linux开发arm音量加减代码,arm-linux学习:最简驱动模块(示例代码)
  7. 苹果手机远程服务器桌面,如何进行远程管理?如何实现苹果手机远程管理电脑?...
  8. Matlab调用Python函数,出现OSError: [WinError 126] 找不到指定的模块报错
  9. jquery Boxy的使用方法
  10. 博客上云历程(二):Docker入门介绍与使用
  11. GIS领域常用软件工具(框架)介绍与推荐
  12. 使用VPS时的注意事项
  13. ivue-admin Table单元格内换行问题
  14. Camtasia2023最好用的电脑屏幕录制软件
  15. 虚拟服务器 vmotion,不使用 vMotion 将 VMware 虚拟机从一台主机迁移至另一台主机...
  16. 驻场开发让我学到了哪些?
  17. 逼死强迫症的腾讯网迷你新闻弹窗
  18. 【自然语言处理】【数据增强】PromDA:应用于低资源NLU任务的、基于prompt的数据增强方法
  19. 【Spring Boot】整合JPA模糊分页查询
  20. excel补充操作技能2--vlookup函数、Match和Index函数、使用函数统计

热门文章

  1. 江西计算机奥赛试题初赛小学组,STEAM教育丨江西省第十八届中小学电脑制作技能提升活动创客竞赛圆满落幕!...
  2. linux直接安装run文件,[Linux]如何安装.run文件
  3. HDU - 4966 GGS-DDU (最小树形图)
  4. ONF组织的SDN架构文档——四个架构(三/二)
  5. html在线填空题,HTML基础练习题目
  6. 众美集团携手行业伙伴 聚焦城镇创新与城市更新
  7. 一般来说,做网站步骤有哪些?
  8. 小甲鱼第1-4章(未整理)
  9. kafka Java客户端之Connect API
  10. java groupbyu_Java8的groupBy实现集合的分组