【问题标题】:Android: Crash when setting up media route buttonAndroid:设置媒体路由按钮时崩溃
【发布时间】:2017-03-27 05:28:37
【问题描述】:

我遇到的问题与Android: Cast SDK v3 Crashing in Release build only 几乎相同。 关键的区别是我的项目在我只是调试的时候就这样做了,而且是在这一行上做的

CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), mMediaRouteButton);

我已尝试公开所有变量,但这无济于事。完整代码是

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mMediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
    CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), mMediaRouteButton);

    mCastContext = CastContext.getSharedInstance(this);

    mSelector = new MediaRouteSelector.Builder()
            // These are the framework-supported intents
            .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
            .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
            .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
            .build();
    mMediaRouter = MediaRouter.getInstance(this);
}

我还发现值得一提的是,这段代码有效,但我终其一生都无法弄清楚是什么原因导致它停止工作。据我所知,当我在 Android Studio 中使缓存无效时它停止工作。 这是我遇到的错误

java.lang.RuntimeException: Unable to start activity ComponentInfo{mypackage.package/mypackage.package.MainActivity}: java.lang.IllegalStateException: Failed to initialize CastContext.
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
    at android.app.ActivityThread.-wrap12(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6077)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
    Caused by: java.lang.IllegalStateException: Failed to initialize CastContext.
    at com.google.android.gms.cast.framework.CastContext.zzbb(Unknown Source)
    at com.google.android.gms.cast.framework.CastContext.getSharedInstance(Unknown Source)
    at com.google.android.gms.cast.framework.CastButtonFactory.setUpMediaRouteButton(Unknown Source)
    at mypackage.package.MainActivity.onCreate(MainActivity.java:51)
    at android.app.Activity.performCreate(Activity.java:6664)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
    at android.app.ActivityThread.-wrap12(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6077) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
    Caused by: java.lang.IllegalAccessException: java.lang.Class<mypackage.package.CastOptionsProvider> is not accessible from java.lang.Class<com.google.android.gms.cast.framework.CastContext>
    at java.lang.Class.newInstance(Native Method)
    at com.google.android.gms.cast.framework.CastContext.zzbb(Unknown Source) 
    at com.google.android.gms.cast.framework.CastContext.getSharedInstance(Unknown Source) 
    at com.google.android.gms.cast.framework.CastButtonFactory.setUpMediaRouteButton(Unknown Source) 
    at mypackage.package.MainActivity.onCreate(MainActivity.java:51) 
    at android.app.Activity.performCreate(Activity.java:6664) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
    at android.app.ActivityThread.-wrap12(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6077) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

【问题讨论】:

    标签: android chromecast google-cast


    【解决方案1】:

    您如何初始化媒体CastContext 可能存在问题,要正确初始化CastContext,应用程序必须具有实现OptionsProvider 接口:

    包 com.example.app;

     public class CastOptionsProvider implements OptionsProvider {
         @Override
         public CastOptions getCastOptions(Context appContext) {
             ...
         }
     }
    

    并在 AndroidManifest.xml 中使用键 OPTIONS_PROVIDER_CLASS_NAME_KEY: 指定其完全限定的类名

      ...
         <meta-data
             android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
             android:value="com.example.app.CastOptionsProvider" />
         ...
    

    注意:所有公共方法都必须从主线程调用。

    我做了一些研究,发现了这个相关的 SO 票,它讨论了如何初始化 CastContext:How to initialize CastContext outside of onCreate method

    【讨论】:

    • 是的,我已经有了该代码,但我认为它不会初始化失败的 CastContext。崩溃发生在这一行 CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), mMediaRouteButton);我从link 得到了我的代码,所以它应该可以工作,直到我使 android studio 上的缓存失效。
    【解决方案2】:

    通过公开 CastOptionsProvider 已解决此问题。我不知道为什么会出现这个问题,因为当它不公开时它工作正常,直到它没有公开。我没有在它开始失败的构建上触摸 CastOptionsProvider。 我的 CastOptionsProvider 现在看起来像这样

    public class CastOptionsProvider implements OptionsProvider {
     @Override
     public CastOptions getCastOptions(Context appContext) {
         CastOptions castOptions = new CastOptions.Builder()
                .setReceiverApplicationId(appContext.getString(R.string.app_id))
                .build();
         return castOptions;
     }
     @Override
     public List<SessionProvider> getAdditionalSessionProviders(Context context) {
        return null;
     }
    }
    

    【讨论】:

    • 我有完全相同的经历:CastOptionsProvider 始终是包私有的,应用程序可以毫无问题地运行。然后有一天,我开始看到这篇文章中提到的相同的“无法初始化 CastContext”RuntimeException。将CastOptionsProvider公开解决了。
    【解决方案3】:

    如果这仅在发布构建类型中发生,那么它与 proguard 有关。请将 CastOptionsProvider 类添加到 proguard 文件并重新检查

    -keep class abc.xyz.videocast.CastOptionsProvider { *; }
    

    为了更安全,还可以添加这些类

    -keep class android.support.** { *; }
    -keep class com.google.** { *; }
    

    【讨论】:

    • 你成就了我的一天!我搜索了所有代码,但最终的解决方案是将这一行添加到我的 proguard 文件中。 -keep class abc.xyz.videocast.CastOptionsProvider { *; }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多