我尝试配置Chromecast,但是遇到了RuntimeException并且没有理解原因。以下是来自Fabric的日志:
致命异常:java.lang.RuntimeException:无法启动活动 ComponentInfo {...。activity.TVActivityPhone}: 了java.lang.RuntimeException: com.google.android.gms.dynamite.DynamiteModule $ zza:远程加载 失败。没有发现本地回退。 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2677) 在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2747) 在android.app.ActivityThread.access $ 900(ActivityThread.java:187) 在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1584) 在android.os.Handler.dispatchMessage(Handler.java:111) 在android.os.Looper.loop(Looper.java:194) 在android.app.ActivityThread.main(ActivityThread.java:5877) 在java.lang.reflect.Method.invoke(Method.java) 在java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1020) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)由java.lang.RuntimeException引起: com.google.android.gms.dynamite.DynamiteModule $ zza:远程加载 失败。没有发现本地后备。
这是我的代码:
protected void configureCast() {
mCastContext = CastContext.getSharedInstance(this); // here I've got RuntimeException
if(mCastContext != null) mCastSession = mCastContext.getSessionManager().getCurrentCastSession();
mSessionManagerListener = new CastSessionManagerListener(this);
mSessionManagerListener.setCastConnectionListener(mCastConnectionListener);
}
这是build.gradle:
compile 'com.google.android.gms:play-services-gcm:10.2.0'
compile 'com.google.android.gms:play-services-analytics:10.2.0'
compile 'com.google.android.gms:play-services-location:10.2.0'
compile 'com.google.android.gms:play-services-cast-framework:10.2.0'
任何帮助?
答案 0 :(得分:7)
首先,它与Why I get this error when on google map "Failed to load DynamiteLoader: java.lang.ClassNotFoundException: Didn't find class?中描述的错误项目配置无关。
有一天,我遇到了Fabric中的崩溃事件(1天内大约1300次崩溃)
com.google.android.gms.dynamite.DynamiteModule$zza: Remote load failed. No local fallback
,
com.google.android.gms.dynamite.DynamiteModule$zzc: No acceptable module found. Local version is 0 and remote version is 0
个例外。
我从第一眼看起来并不清楚为什么会发生这种情况,因为我在那段时间内没有发布应用程序的任何更新。经过深入调查(总共几天)后,我发现问题是由Google Play服务版与过时的Google Cast SDK之间的破坏兼容性造成的。
我的Android应用程序使用10.2.4版本的Google Cast SDK,此版本与某些Google Play服务版本不兼容。 我发现11.3.02 (480-161239932)版Google Play服务与 10.2.4 Google Cast SDK不兼容。 (肯定)其他版本的Google Play服务与Google Cast SDK库不兼容,但我发现只有一个,这足以进行测试和进一步修复。
设备上安装了11.3.02 (480-161239932)版本的Google Play服务,我的应用程序在启动后立即崩溃。值得注意的是,我发现我的设备上的其他应用程序在启动时立即崩溃并且堆栈跟踪是相同的。
修复崩溃
修复对我来说很简单 - 我必须将Google Play服务从10.2.4更新为11.4.2 ,
特别是play-services-cast-framework
,play-services-ads
,firebase-core
,firebase-messaging
。
Fabric中的Spikes历史记录:
10月8日之后崩溃并不严重(每天约10-20次崩溃)并且没有观察到尖峰。这意味着用户更新了Google Play服务,应用程序在启动时不再崩溃。
我更新了Google Play服务版本并将用户更新为新版应用程序 - 崩溃消失(每天约1-2次崩溃)。
发生此次崩溃的原因说明
如您所知,Google Play服务会在后台自动更新。这意味着有一天用户可以收到与应用中使用的Google Cast SDK不兼容的Google Play服务更新,应用程序将崩溃(100%)。
根据我的经验,它适用于Google Cast SDK,但其他库可能就是这种情况(没有证据)。
当您从Google Cast SDK调用任何方法时,应用程序崩溃。我在我的应用程序中评论了不同的地方,这些地方依赖于Google Cast SDK并且应用程序总是崩溃。
详细指南
如果有人好奇如何模仿这次崩溃,请参阅此处的详细指南。
在Android设备(apkmirror link)上安装11.3.02(480-161239932)版本的Google Play服务。
adb install -r com.google.android.gms_11.3.02_(480-161239932)-11302480_minAPI23(x86,x86_64)(nodpi)_apkmirror.com.apk
崩溃的第二次到来
我认为我已经通过更新Google Play服务修复了崩溃问题,但是在沉默几周之后,我已经收到通知,表示同一堆栈跟踪重新出现崩溃。
经过一番调查(再过几天),我能够重现这个问题。这是悲伤的消息 - 我对这次崩溃无能为力:sad_face:或者至少我还没有找到优雅的解决方案。
好消息是,重新露面的撞车事故非常罕见(每月约1-2次撞车事故)。
Google Play服务自动更新或强制卸载(不太可能)强制停止打开应用程序以使Play服务更新生效。这是一个无法控制的过程,这意味着Android操作系统可以随时静默安装Google Play服务。 如果用户打开了应用程序并且Google Play服务安装在某个时刻完成,系统将终止应用程序并且用户需要重新打开它。当应用程序被系统杀死时,我们可以看到在日志中,崩溃的堆栈跟踪与第一种情况完全相同。 很难再现,只发生在我身上几次。 但这种情况更可能是因为Google Play服务经常更新。
虽然有一种方法可以重现此次崩溃(在现实生活中可能性较小) - "从设备" 中删除Google Play服务更新。它产生相同的堆栈跟踪。
基本上,我们需要开始删除Google Play服务更新并快速(我的意思是很快)打开我们的应用程序。如果我们成功,该应用程序将在启动时被系统杀死,因为Google Play服务已被删除,系统会杀死该应用程序。
这是堆栈跟踪:
FATAL EXCEPTION: main
Process: XXX, PID: 26149
java.lang.RuntimeException: Unable to start activity ComponentInfo{XXX/XXX.SomeActivity}: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2733)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2819)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1532)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6321)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #0: Error inflating class fragment
Caused by: java.lang.RuntimeException: com.google.android.gms.dynamite.DynamiteModule$zzc: No acceptable module found. Local version is 0 and remote version is 0.
at com.google.android.gms.internal.zzavl.zzbp(Unknown Source)
at com.google.android.gms.internal.zzavl.zza(Unknown Source)
at com.google.android.gms.cast.framework.CastContext.<init>(Unknown Source)
at com.google.android.gms.cast.framework.CastContext.getSharedInstance(Unknown Source)
at com.google.android.gms.cast.framework.media.uicontroller.UIMediaController.<init>(Unknown Source)
at com.google.android.gms.cast.framework.media.widget.MiniControllerFragment.onCreateView(Unknown Source)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2343)
at android.support.v4.app.FragmentManagerImpl.ensureInflatedFragmentView(FragmentManager.java:1645)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1390)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1640)
at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1896)
at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3673)
at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111)
at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:331)
at android.support.v4.app.BaseFragmentActivityApi14.onCreateView(BaseFragmentActivityApi14.java:39)
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:65)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:777)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
at XXX.SomeActivity.setContentView(SomeActivity:XXX)
at XXX.SomeActivity.onCreate(SomeActivity:XXX)
at android.app.Activity.performCreate(Activity.java:6760)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134)
更新
有一个Google Play Services 12.0.0 release,它可以解决问题:
修复了在使用过时版Google Play服务的设备上调用CastContext.getSharedInstance()导致崩溃的错误。过时的Google Play服务版本仍会导致该方法失败,因此客户应检查相应的版本。
但事实上,即使在更新到12.0.0版本后,我也发现了很多崩溃事件。当设备上发生Google Play服务更新时,就会发生崩溃。 要解决此问题,我们需要通过检查在调用Cast API时是否未抛出异常来检查Cast API是否可用。
fun isCastApiAvailable(): Boolean {
val isCastApiAvailable = isNotTv(context)
&& GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS
try {
CastContext.getSharedInstance(context)
} catch (e: Exception) {
// track non-fatal
return false
}
return isCastApiAvailable
}
这样我们就可以防止崩溃。如果在应用程序位于前台时发生Play Services更新,则系统可能会终止并重新启动应用程序。或者,Cast API相关功能无法使用(Chromecast图标不可见)。 因此,我们以这种方式避免崩溃并报告为非致命性,只是为了了解这种情况发生的频率。