这个问题多出现在三星制造的搭载 Android 4.3 系统的手机上。
问题的原因是在 ActivityThread 回收内存时会调用 com.google.android.gles_jni.EGLImpl
类相关方法,并回收 RenderThread
,进而调用到计算 CPU FPS
的逻辑,导致 crash
:
native stacktrace
#00 pc 0x00002d4c /system/lib/libPowerStretch.so (LucidConfig::calcTargetFPS(int))
#01 pc 0x00002f23 /system/lib/libPowerStretch.so (LucidConfig::isLucidActive(bool))
...
at dalvik.system.NativeStart.run(Native Method)
main
at com.google.android.gles_jni.EGLImpl.eglReleaseThread(Native Method)
at android.view.HardwareRenderer$Gl20Renderer$Gl20RendererEglContext.onTerminate(HardwareRenderer.java:1743)
at android.opengl.ManagedEGLContext.execTerminate(ManagedEGLContext.java:84)
at android.opengl.ManagedEGLContext.doTerminate(ManagedEGLContext.java:132)
at android.view.WindowManagerGlobal.endTrimMemory(WindowManagerGlobal.java:460)
at android.app.ActivityThread.handleTrimMemory(ActivityThread.java:4374)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1531)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
...
问题出在系统层面,Android 应用回收内存的 Message 是 ActivityManager 发出,属于系统正常行为,无法规避。
解决方法:
- 定义一个渲染策略类,针对 samsung + android 4.3这种组合在
WebView layer
层面关闭硬件加速。(这样就不会存在RenderThread
,自然也就没法触发上文的crash
)
public static boolean shouldDisableHardwareRenderInLayer() {
// case 1: samsung GS4 on android 4.3 is know to cause crashes at libPowerStretch.so:0x2d4c
// use GT-I95xx to match more GS4 series devices though GT-I9500 is the typical device
final boolean isSamsungGs4 =
android.os.Build.MODEL != null &&
android.os.Build.MODEL.contains("GT-I95") &&
android.os.Build.MANUFACTURER != null &&
android.os.Build.MANUFACTURER.equals("samsung");
final boolean isJbMr2 = Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR2;
return isSamsungGs4 && isJbMr2;
}
- 在自定义
WebView
中使用以上渲染策略类。
final boolean meetApiLevel11 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
if (shouldDisableHardwareRenderInLayer() && meetApiLevel11) {
try {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
} catch (Exception globalException) {
globalException.printStackTrace();
}
}
网友评论