IntentService报错 java.lang.InstantiationException

本文探讨了在使用IntentService时遇到的常见错误之一:java.lang.InstantiationException。主要原因是忽视了创建无参构造函数的重要性。通过实例分析,解释了错误的根本原因,并提供了正确的解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在startService起来一个IntentService报错,异常为java.lang.InstantiationException,主要原因是忘了写无参构造函数了。

<think>嗯,用户现在在分析Android系统亮灭屏后出现ANR的问题,特别是和主线程等待状态相关的代码路径,比如GLSurfaceView的readySurface、MainThread的tick等。我之前已经给过一些分析步骤,现在用户进一步深入,结合引用内容,可能需要更具体的代码路径和机制分析。首先,用户提供的引用中提到了GLSurfaceView的特性,比如管理Surface、EGL Display,渲染器在独立线程运行(引用1)。这可能和渲染线程与主线程的交互有关。如果亮灭屏时Surface的状态变化导致主线程等待渲染线程,可能会引发ANR。比如,主线程在等待GLSurfaceView的surfaceready时被阻塞,超过5秒就会触发ANR。引用2提到主线程不能做耗时操作,否则会导致ANR。如果亮灭屏时,主线程在处理相关回调(如onPause、onResume)时,有同步操作涉及GLSurfaceView的surface准备,可能阻塞主线程。比如,在Activity的onResume中同步等待GLSurfaceView的surface创建完成,这样主线程就会被卡住。引用3和4涉及Service和Activity的生命周期,可能用户在亮灭屏时,相关生命周期方法被调用,如果这些方法中有同步操作,也可能导致ANR。比如,在onCreate或onStart中执行了耗时操作,或者GLSurfaceView的初始化没有放在子线程,导致主线程卡顿。 接下来,我需要结合这些引用,分析亮灭屏时主线程可能被阻塞的代码路径。比如,当屏幕关闭时,系统可能会调用onPause,GLSurfaceView可能会销毁Surface,而屏幕重新打开时,需要重新创建Surface。如果这个过程是同步的,主线程就会等待,导致ANR。另外,GLSurfaceView的渲染线程是否和主线程有同步点?比如,当surface被销毁或重新创建时,主线程是否需要等待渲染线程完成某些操作?如果渲染线程在处理某些任务时耗时过长,主线程可能在等待时触发ANR。 可能的代码路径包括:1.Activity的生命周期方法(如onResume)中调用GLSurfaceView的onResume,这会触发surface的创建,如果这个过程是同步的,并且涉及主线程等待渲染线程的响应,就会导致阻塞。 2.主线程在处理WindowManagerService的窗口状态变化时,需要同步更新Surface的状态,如果Surface相关的操作(如eglSwapBuffers)卡住,主线程会被阻塞。需要检查GLSurfaceView的源码,特别是主线程和渲染线程之间的交互。比如,GLThread和主线程之间的消息传递,是否有锁竞争或同步等待的情况。例如,当surface创建时,GLThread可能需要初始化EGL环境,而主线程在等待这个过程完成。此外,亮灭屏时,PowerManagerService和WindowManagerService会调整显示状态,可能触发ViewRootImpl的performTraversals,这会涉及到measure、layout、draw,如果draw过程中需要等待GLSurfaceView的渲染完成,而渲染线程此时无法及时处理,主线程就会卡住。 可能还需要检查Choreographer的VSYNC信号处理,主线程的doFrame方法中是否因为GLSurfaceView的渲染未完成而延迟执行,导致后续的UI操作堆积,引发ANR。 另外,引用2提到主线程应避免耗时操作,使用Handler或异步任务。如果三方应用在亮灭屏广播接收器中执行了同步的GL操作,或者在主线程中直接操作GLSurfaceView,而没有异步处理,就会导致ANR。总结可能的ANR触发点: -主线程在亮灭屏时同步等待GLSurfaceView的surface准备完成。 -渲染线程处理时间过长,导致主线程在VSYNC周期内无法完成帧绘制。 -三方应用在广播接收器中执行了GL相关操作,阻塞主线程。需要结合具体的堆栈日志(traces.txt)和Systrace分析,查看主线程在ANR时的状态,是否在等待锁或阻塞在GLSurfaceView的相关方法上。</think>### Android亮灭屏ANR分析(主线程等待与GLSurfaceView相关) --- #### 一、关键代码路径分析 1. **GLSurfaceView渲染线程与主线程交互**: - GLSurfaceView的`onResume()`会触发渲染线程初始化EGL环境并创建Surface[^1] ```java // frameworks/base/core/java/android/opengl/GLSurfaceView.java public void onResume() { mGLThread.onResume(); // 主线程等待渲染线程完成surface创建 } ``` - 渲染线程通过`GLThread.guardedRun()`处理`surfaceCreated`事件,若耗时超过16ms(VSYNC周期),主线程可能阻塞在`Choreographer`回调中[^2] 2. **亮灭屏触发的主线程操作**: ```java // frameworks/base/core/java/android/view/WindowManagerGlobal.java private void handleScreenStateChange(int displayId, boolean isScreenOn) { mRoot.performTraversals(); // 触发视图树重绘 // 包含GLSurfaceView的视图需要重新绑定Surface } ``` - 若`performTraversals()`中需要等待`GLSurfaceView`完成渲染准备,主线程将进入阻塞状态 3. **主线程等待的典型场景**: $$ \text{ANR触发条件} = \text{主线程等待时间} \geq 5\text{秒} $$ - `GLSurfaceView.readySurface()`中的同步锁竞争: ```java synchronized(mGLThreadManager) { while (!mEglHelper.createSurface()) { mGLThreadManager.wait(); // 主线程可能在此等待 } } ``` --- #### 二、ANR触发模式验证 1. **Systrace分析**: ```shell adb shell atrace -b 16384 gfx input view wm am ss sched freq idle binder_driver ``` - 观察`RenderThread`与`main`线程的协作时序,例如: - `doFrame`中`draw`阶段卡在`eglSwapBuffers` - `Choreographer`回调延迟超过多个VSYNC周期 2. **ANR日志关键标识**: ``` "main" prio=5 tid=1 Native | group="main" sCount=1 dsCount=0 flags=1 obj=0x74e07000 | sysTid=3021 nice=0 cgrp=default sched=0/0 handle=0x7a8e4500 | state=S schedstat=( 123456789 987654321 1234 ) utm=12 stm=5 core=0 HZ=100 | stack=0x7fccb3a000-0x7fccb3c000 | held mutexes= kernel: __switch_to+0xb4/0xdc native: #00 pc 000000000007a4d4 /system/lib64/liba.so (eglSwapBuffers+0x1c) native: #01 pc 0000000000012345 /system/lib64/libandroid_runtime.so (???) at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1524) at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1350) ``` - 主线程在`eglSwapBuffers`处阻塞时,可能由渲染线程未及时完成帧提交导致[^1] --- #### 三、优化方案 1. **GLSurfaceView异步化改造**: ```diff // 修改GLSurfaceView的surface创建逻辑 - mGLThread.onResume(); // 同步调用 + new Handler().post(() -> mGLThread.onResume()); // 异步化 ``` 2. **主线程关键路径优化**: ```java // 避免在ViewRootImpl中直接同步等待 public void performTraversals() { if (!mSurface.isValid()) { scheduleTraversals(); // 改为异步重试 return; } // 正常执行绘制 } ``` 3. **三方应用适配要求**: - 在`BroadcastReceiver`中处理亮灭屏事件时,必须使用`IntentService`或`HandlerThread`[^2] ```xml <receiver android:name=".ScreenReceiver"> <intent-filter> <action android:name="android.intent.action.SCREEN_ON"/> <action android:name="android.intent.action.SCREEN_OFF"/> </intent-filter> </receiver> ``` --- #### 四、数学建模分析 设主线程的帧处理时间为$T_{main}$,渲染线程的帧处理时间为$T_{render}$,则系统稳定性需满足: $$ T_{main} + T_{render} \leq \frac{1}{FPS} $$ 当亮灭屏导致Surface重建时,额外引入延迟$\Delta T$,此时ANR概率为: $$ P(ANR) = \begin{cases} 1, & \text{当 } T_{main} + \Delta T \geq 5\text{秒} \\ 0, & \text{否则} \end{cases} $$ ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值