• 安卓开发中遇到的奇奇怪怪的问题(四)


    在这里插入图片描述
    好久没有写这个系列了,感觉还是需要把日常开发中遇到的问题做一个记录总结,因为有些问题我当时遇到时,搜都搜不到,只能慢慢摸索。帮助他人的同时也能给自己留个备忘录。话不多说,凡是近一年的奇怪问题,我想起一个会补充一个。

    1.适配Android 12应用启动画面

    如果windowSplashScreenAnimatedIcon设置的是静态图片,即使你用的是矢量图,开屏是图片还是会模糊。最后发现使用动态矢量图就清晰了。。。可以用标签包裹原先的静态图,示例如下:

    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:aapt="http://schemas.android.com/aapt">
        <aapt:attr name="android:drawable">
            <vector .../>
        aapt:attr>
    animated-vector>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    也不知道具体是什么原因,只是当我发现Gmail的启动画面是正常的时,怀疑是不是需要用动态矢量图。结果一试发现果然正常了。

    上线后发现了另一个问题,个别Android 12设备上出现了三种崩溃,由多到少排序如下:

    Fatal Exception: java.lang.IllegalArgumentException: Activity client record must not be null to execute transaction item
           at android.app.servertransaction.ActivityTransactionItem.getActivityClientRecord(ActivityTransactionItem.java:85)
           at android.app.servertransaction.ActivityTransactionItem.getActivityClientRecord(ActivityTransactionItem.java:58)
           at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:43)
           at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
           at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'com.android.server.wm.DisplayContent com.android.server.wm.WindowContainer.getDisplayContent()' on a null object reference
           at android.os.Parcel.createExceptionOrNull(Parcel.java:2432)
           at android.os.Parcel.createException(Parcel.java:2410)
           at android.os.Parcel.readException(Parcel.java:2393)
           at android.os.Parcel.readException(Parcel.java:2335)
           at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:2377)
           at android.app.Instrumentation.execStartActivity(Instrumentation.java:1808)
           at android.app.Activity.startActivityForResult(Activity.java:5506)
           at androidx.activity.ComponentActivity.startActivityForResult(SourceFile:2)
           at android.app.Activity.startActivityForResult(Activity.java:5464)
           at androidx.activity.ComponentActivity.startActivityForResult(SourceFile:1)
           at android.app.Activity.startActivity(Activity.java:5854)
           at android.app.Activity.startActivity(Activity.java:5807)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    下面这个都是Android12的小米手机,机型型号:Redmi 9T,Redmi Note 9 Pro,Redmi Note 11 Pro 5G,Poco M2 Pro:

    Fatal Exception: java.lang.IllegalArgumentException: reparent: can't reparent to null, mParent is nullWindow{37a85c8 u0 Splash Screen com.xxx}
           at android.os.Parcel.createExceptionOrNull(Parcel.java:2430)
           at android.os.Parcel.createException(Parcel.java:2410)
           at android.os.Parcel.readException(Parcel.java:2393)
           at android.os.Parcel.readException(Parcel.java:2335)
           at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:2721)
           at android.app.Instrumentation.execStartActivity(Instrumentation.java:1745)
           at android.app.Activity.startActivityForResult(Activity.java:5482)
           at androidx.activity.ComponentActivity.startActivityForResult(SourceFile:2)
           at android.app.Activity.startActivityForResult(Activity.java:5440)
           at androidx.activity.ComponentActivity.startActivityForResult(SourceFile:1)
           at android.app.Activity.startActivity(Activity.java:5826)
           at android.app.Activity.startActivity(Activity.java:5779)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    记得当时统计到一天会崩溃2次左右,这三种崩溃总计影响了近80位用户。

    Android 13上会出现崩溃如下:

    Fatal Exception: java.lang.NullPointerException: Attempt to invoke direct method 'void android.view.SurfaceControl.checkNotReleased()' on a null object reference
           at android.view.SurfaceControl.-$$Nest$mcheckNotReleased()
           at android.view.SurfaceControl$Transaction.checkPreconditions(SurfaceControl.java:2896)
           at android.view.SurfaceControl$Transaction.hide(SurfaceControl.java:3079)
           at android.app.ActivityThread.syncTransferSplashscreenViewTransaction(ActivityThread.java:4359)
           at android.app.ActivityThread.-$$Nest$msyncTransferSplashscreenViewTransaction()
           at android.app.ActivityThread$1.onDraw(ActivityThread.java:4336)
           at android.view.ViewTreeObserver.dispatchOnDraw(ViewTreeObserver.java:1132)
           at android.view.ViewRootImpl.draw(ViewRootImpl.java:4805)
           at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4572)
           at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3758)
           at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2458)
           at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9466)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这个总共崩溃14次,对于大多数用户是Android 13系统来说,相对比较低。

    后面我也查询到了相关问题:

    结论是Android 源码中的一个bug,但是另我不解的是当时另外一个产品也做了相关适配,但是没有此类问题。后面对比发现是多了下面这个方法:

    getSplashScreen().setOnExitAnimationListener(new SplashScreen.OnExitAnimationListener() {
        @Override
        public void onSplashScreenExit(@NonNull SplashScreenView splashScreenView) {
            splashScreenView.remove();
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    加这个目的是原因是个别手机上SplashScreen和页面过渡时会有淡入淡出的切换动画。为了过渡“无感”,所以加了这个监听方法,在SplashScreen结束时直接移除。

    一开始以为是remove导致的空指针,所以一开始的修复方式是改为隐藏splashScreenView.setVisibility(View.GONE),然后上线后发现无效。。。最后只能是删除了这个监听,之后就没有崩溃了。

    因为是个别机型个别系统版本的问题,所以也不方便去找这些厂家的源码去一探究竟。所以只能是去线上快速试错,好在此类崩溃不多,否则真是会让人头疼不已。

    2. Gson与Gradle

    年初将Gradle从7.0.2升到7.2.2后,发现release包运行崩溃了。

    Fatal Exception: java.lang.RuntimeException: Missing type parameter.
    	com.google.gson.reflect.TypeToken.getSuperclassTypeParameter (TypeToken.java:84)
    	com.google.gson.reflect.TypeToken.<init> (TypeToken.java:62)
    
    • 1
    • 2
    • 3

    看到异常报到了Gson上面,所以我就去gson项目下搜了一下相关异常,结果如下:(gson版本是2.8.5)

    相关问题:

    原因是R8 3.0版本开始从未在完整模式下(full mode)与-keep规则匹配的项目中删除通用签名。此更改的动机是避免在程序中保留所有通用签名,而通常只需要少数通用签名用于反射。

    解决方法,添加混淆配置:

    -keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
    -keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
    
    • 1
    • 2

    3. 混淆与WebView

    混淆添加 android.webkit.** 后,需要注意将包下用的的类进行混淆,否则使用到某些方法会报VerifyError异常。例如SslError类:

    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    }
    
    • 1
    • 2

    所以需要补充 -keep class android.net.http.** { *; } 混淆配置。或者不添加webkit的混淆。

    4. 锁屏后handler计时失效

    可以参考这篇的解决方法:Android 锁屏后handler计时失效

    5. 静音与投屏

    这个是最近出现的问题。项目中的视频在播放时,有段逻辑会触发"取消静音"的操作,这块发生了崩溃,问题代码:

    AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    mAudioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
    
    • 1
    • 2

    Android 13 ,机型:Galaxy Z Flip4 / Galaxy Z Flip3 / Galaxy Z Fold4 ,异常如下:

    Fatal Exception: java.lang.SecurityException: Permission required to call setVolumeKeyEvent: Neither user 10188 nor current process has android.permission.CONFIGURE_WIFI_DISPLAY.
           at android.os.Parcel.createExceptionOrNull(Parcel.java:3023)
           at android.os.Parcel.createException(Parcel.java:3007)
           at android.os.Parcel.readException(Parcel.java:2990)
           at android.os.Parcel.readException(Parcel.java:2932)
           at android.media.IAudioService$Stub$Proxy.adjustStreamVolumeWithAttribution(IAudioService.java:4666)
           at android.media.AudioManager.adjustStreamVolume(AudioManager.java:971)
           at android.media.AudioManager.setStreamMute(AudioManager.java:1506)
    
    Caused by android.os.RemoteException: Remote stack trace:
    	at android.app.ContextImpl.enforce(ContextImpl.java:2359)
    	at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:2387)
    	at com.android.server.display.DisplayManagerService$BinderService.setVolumeKeyEvent(DisplayManagerService.java:4566)
    	at android.hardware.display.DisplayManagerGlobal.setVolumeKeyEvent(DisplayManagerGlobal.java:1196)
    	at android.hardware.display.DisplayManager.semSetWifiDisplayConfiguration(DisplayManager.java:2489)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    提示没有CONFIGURE_WIFI_DISPLAY权限,但是这个权限只授予系统应用程序。这个权限是允许应用程序配置和连接到Wifi显示器的,通常用做系统无线投屏(Miracast)。

    我查到同样机型和系统且能触发这块代码的用户一百多人,目前出现此问题的只有四人。(十天时间)

    在这里插入图片描述

    我能想到的是,用户可能有使用三星系统自带的Smart View来进行投屏。因为使用App同时使用系统投屏功能本就是少数(因为App中有投屏功能),且这个功能不是最近才有的。这样突然集中出现,且都是三星的设备,只能大概率怀疑是手机系统更新后出现的新问题。

    目前处理方法只能先加上异常捕获,改为错误上报,持续观察一下。后面有进展了会补充到这里。

    6. 其他

    • 华为部分手机侧滑返回区域(两侧大概各50dp)会有滑动冲突。Seekbar在这个区域内无法滑动(可点击)。
  • 相关阅读:
    使用Dockerfile部署springboot项目 (入门级教程 简单易懂)
    【shiro】Apache Shiro 1.2.4 反序列化漏洞(CVE-2016-4437 )
    2022-04-25-ElasticSearch
    【深圳X金技术公司】Java笔试题
    不开辟新存储空间的情况下完成链表的逆置
    RF电路设计常见bug及解决方法
    2023计算机毕业设计SSM最新选题之java企业绩效考核系统x73jw
    您知道Jmeter中Redirect Automatically 和 Follow Redirects的使用场景吗?
    Python3.11正式版,它来了!
    QT找不到ffmpeg链接库解决方法
  • 原文地址:https://blog.csdn.net/qq_17766199/article/details/133494759