Android:设置媒体路由按钮时崩溃

时间:2016-11-13 13:03:31

标签: android chromecast google-cast

我和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) 

3 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:3)

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

package 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

答案 2 :(得分:3)

这是通过将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;
 }
}