在Xamarin上调试Java.Lang.RuntimeException

本文关键字:Lang RuntimeException Java 调试 Xamarin | 更新日期: 2023-09-27 17:51:26

由于这个java,我发布的游戏不一致地崩溃。2月底以来的例外。大约10分钟后(游戏邦注:根据我的经验,可能是1分钟到30分钟甚至60分钟,甚至根本不会发生),游戏就会崩溃。即使在2小时的游戏后,我也无法使用连接的调试器重现崩溃。

我正在使用Hockeyapp报告应用程序崩溃,但堆栈跟踪是绝对空的:

Package: hb.doom_and_destiny_advanced
Version: 1516
Android: 5.1.1
Manufacturer: HUAWEI
Model: HUAWEI SCL-L01
Date: 24/06/2016 22:25:51
Java.Lang.RuntimeException: Only the original thread that created a view hierarchy can touch its views.

似乎没有明显的失败原因,游戏没有使用UI系统,如果不是在一夫一妻制框架下。经过几个月的测试,我真的忍不住请求一些帮助来调试这个严重使我发疯的错误。

目前的主要问题是无法在一致和可行的测试时间内重现崩溃:它可以在1分钟或超过60分钟内发生,并且它似乎在某种程度上受到用户交互的影响(例如,我在运行基准测试时从未能够看到错误)。

检查android日志也没有帮助,因为它们包含了来自许多android系统的非常令人困惑的信息,但是,就mono而言,它一点也不冗长。

06-20 19:04:16.917: W/ls(27999): type=1400 audit(0.0:3522): avc: denied { getattr } for path="/init" dev="rootfs" ino=5443 scontext=u:r:shell:s0 tcontext=u:object_r:init_exec:s0 tclass=file permissive=0
06-20 19:04:16.917: W/ls(27999): type=1400 audit(0.0:3523): avc: denied { getattr } for path="/persist" dev="mmcblk0p16" ino=2 scontext=u:r:shell:s0 tcontext=u:object_r:persist_file:s0 tclass=dir permissive=0
06-20 19:04:18.068: D/ConnectivityService(772): notifyType CAP_CHANGED for NetworkAgentInfo [WIFI () - 101]
06-20 19:04:19.215: W/SoundPool(12501):   sample 1 not READY
06-20 19:04:19.254: I/OMXClient(12501): Using client-side OMX mux.
06-20 19:04:19.258: E/OMXMaster(12501): A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
06-20 19:04:19.418: W/AudioTrack(12501): AUDIO_OUTPUT_FLAG_FAST denied by client; transfer 4, track 44100 Hz, output 48000 Hz
06-20 19:04:19.419: D/audio_hw_primary(198): out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
06-20 19:04:19.430: D/audio_hw_primary(198): select_devices: out_snd_device(2: speaker) in_snd_device(0: none)
06-20 19:04:19.430: D/msm8974_platform(198): platform_send_audio_calibration: sending audio calibration for snd_device(2) acdb_id(15)
06-20 19:04:19.430: D/audio_hw_primary(198): enable_audio_route: apply and update mixer path: low-latency-playback
06-20 19:04:19.608: I/art(12501): Starting a blocking GC Explicit
06-20 19:04:19.624: I/art(12501): Explicit concurrent mark sweep GC freed 3391(130KB) AllocSpace objects, 3(604KB) LOS objects, 25% free, 46MB/62MB, paused 265us total 15.711ms
06-20 19:04:21.082: D/ConnectivityService(772): notifyType CAP_CHANGED for NetworkAgentInfo [WIFI () - 101]
06-20 19:04:21.941: D/audio_hw_primary(198): out_set_parameters: enter: usecase(0: deep-buffer-playback) kvpairs: routing=2
06-20 19:04:21.927: W/ls(28029): type=1400 audit(0.0:3524): avc: denied { getattr } for path="/init" dev="rootfs" ino=5443 scontext=u:r:shell:s0 tcontext=u:object_r:init_exec:s0 tclass=file permissive=0
06-20 19:04:21.927: W/ls(28029): type=1400 audit(0.0:3525): avc: denied { getattr } for path="/persist" dev="mmcblk0p16" ino=2 scontext=u:r:shell:s0 tcontext=u:object_r:persist_file:s0 tclass=dir permissive=0
06-20 19:04:22.278: W/SoundPool(12501):   sample 2 not READY
06-20 19:04:22.292: I/OMXClient(12501): Using client-side OMX mux.
06-20 19:04:22.296: E/OMXMaster(12501): A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
06-20 19:04:22.479: W/AudioTrack(12501): AUDIO_OUTPUT_FLAG_FAST denied by client; transfer 4, track 44100 Hz, output 48000 Hz
06-20 19:04:22.490: D/audio_hw_primary(198): out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
06-20 19:04:22.527: D/AudioFlinger(198): mixer(0xb41c0000) throttle end: throttle time(4)
06-20 19:04:22.941: D/audio_hw_primary(198): out_set_parameters: enter: usecase(0: deep-buffer-playback) kvpairs: routing=2
06-20 19:04:25.784: D/audio_hw_primary(198): disable_audio_route: reset and update mixer path: low-latency-playback
06-20 19:04:26.927: W/ls(28070): type=1400 audit(0.0:3526): avc: denied { getattr } for path="/init" dev="rootfs" ino=5443 scontext=u:r:shell:s0 tcontext=u:object_r:init_exec:s0 tclass=file permissive=0
06-20 19:04:26.927: W/ls(28070): type=1400 audit(0.0:3527): avc: denied { getattr } for path="/persist" dev="mmcblk0p16" ino=2 scontext=u:r:shell:s0 tcontext=u:object_r:persist_file:s0 tclass=dir permissive=0
06-20 19:04:27.114: D/ConnectivityService(772): notifyType CAP_CHANGED for NetworkAgentInfo [WIFI () - 101]
06-20 19:04:28.947: I/art(12501): Starting a blocking GC Explicit
06-20 19:04:28.960: I/art(12501): Explicit concurrent mark sweep GC freed 2256(88KB) AllocSpace objects, 0(0B) LOS objects, 25% free, 46MB/62MB, paused 285us total 12.462ms
06-20 19:04:28.984: I/mono-stdout(12501): Writing unhandled exception to: /data/user/0/hb.doom_and_destiny_advanced/files/77b60833-c767-4692-9068-4b829619d394.stacktrace

游戏确实使密集的使用网络呼叫,所以我想,也许android试图显示一个弹出,如果有不一致的连接。由于弹出窗口可能是从次要任务/线程中调用的,它可能会崩溃,因为在Xamarin的mono实现中缺少"runonuthread"。

如果是这种情况,我可以通过发布旧版本的Xamarin Android来检查它,但Gen 2016版本不再可供下载。

在将异常日志软件更新到最新版本后,错误日志似乎更有信息,我仍然不知道哪个线程正在崩溃,但我肯定在搜索中得到更多的命中。

由:android.runtime.JavaProxyThrowable: System。AggregateException:等待任务或访问其exception属性时未观察到任务的异常。结果,未观察到的异常被终结器线程重新抛出。Java.Lang.RuntimeException:只有创建视图层次结构的原始线程可以触摸它的视图。——内部异常堆栈跟踪结束——-->(内部异常#0)Java.Lang.RuntimeException:只有创建视图层次结构的原始线程可以触摸它的视图。<——

at dalvik.system.NativeStart.run(Native Method)

似乎有两个问题的组合:

1)一个任务正在崩溃,可能是由于

(Inner Exception #0) Java.Lang.RuntimeException: Only the original thread that created a view hierarchy can touch its views.<---

2)一旦gc收集任务,异常被重新抛出并使用外部

终止应用程序。
System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property.

在Xamarin上调试Java.Lang.RuntimeException

看到这两个步骤并添加到我的代码库

  1. 从所有的oncreate调用这个方法HandleGlobalExceptions()
  2. 创建一个基本活动并覆盖oncreate of基活动并调用此方法要添加的示例代码

    using ar = Android.Runtime;

        public static void HandleGlobalExceptions()
            {
                AppDomain currentDomain = AppDomain.CurrentDomain;
                currentDomain.UnhandledException += HanldleDomainGlobalException;
                ar.AndroidEnvironment.UnhandledExceptionRaiser += HandleAndroidEnvException;
            }
    

    这两个帮助被称为

            private static void HandleAndroidEnvException(object sender, ar.RaiseThrowableEventArgs e)
            {
                Log.Wtf("EnvGlobal", e.Exception.ToString());
     // display or handle error here , the way uwant           
            }
            private static void HanldleDomainGlobalException(object sender, UnhandledExceptionEventArgs e)
            {
                Log.Wtf("DomainGlobal", e?.ExceptionObject?.ToString());
     // display or handle error here , the way uwant
            }
    

因此,正如我在我的最新发现中所建议的那样,崩溃是由于任务抛出异常,并等待垃圾收集器完成以重新抛出异常。

这很难调试,因为我没有得到完整的异常层次结构,因为我在崩溃报告软件中使用修改的异常处理程序,这只提取最新的"InnerException"。

实际的异常是我试图从一个不是视图创建线程的线程中禁用自动屏幕调光