8

歸檔臭蟲Android版YouTube播放器API庫工程師:看到Android的YouTube上的API標籤Android版YouTube播放器API將引發新的YouTube版本

在過去一週的過程中一半,我已經注意到這個奇怪的BadParcelableException在我們的應用程序中穩步增加,並已將它釘在YouTube上的新版本的Android上。如果您的應用程序正在播放YouTube視頻,把你的應用的背景下,力停止YouTube應用,並重新恢復你的應用程序將發生

這個崩潰。在Youtube版本12.19.56上重現崩潰。還在較舊的YouTube版本12.05.21上進行了測試,崩潰不在那裏。

堆棧跟蹤:

main Exception: Unable to start activity ComponentInfo{com.myapp.MainActivity}: 
android.os.BadParcelableException: ClassNotFoundException when unmarshalling: asc 
Stack: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.MainActivity}: 
android.os.BadParcelableException: ClassNotFoundException when unmarshalling: asc 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2666) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1478) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6121) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) Caused by: 
android.os.BadParcelableException: ClassNotFoundException when unmarshalling: asc 
at android.os.Parcel.readParcelableCreator(Parcel.java:2536) 
at android.os.Parcel.readParcelable(Parcel.java:2462) 
at android.os.Parcel.readValue(Parcel.java:2365) 
at android.os.Parcel.readSparseArrayInternal(Parcel.java:2813) 
at android.os.Parcel.readSparseArray(Parcel.java:2068) 
at android.os.Parcel.readValue(Parcel.java:2422) 
at android.os.Parcel.readArrayMapInternal(Parcel.java:2732) 
at android.os.BaseBundle.unparcel(BaseBundle.java:269) 
at android.os.Bundle.getSparseParcelableArray(Bundle.java:934) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1208) 
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595) 
at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:2893) 
at android.support.v4.app.FragmentController.dispatchCreate(FragmentController.java:190) 
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:353) 
at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:85) 
at com.myapp.BaseActivity.onCreate(BaseActivity.java:36) 
at com.myapp.MainActivity.onCreate(MainActivity.java:190) 
at android.app.Activity.performCreate(Activity.java:6682) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2619) ... 9 more 

Caused by: java.lang.ClassNotFoundException: Didn't find class "asc" on path: DexPathList[[zip file "/data/app/com.myapp-naA-_cCrz-w81rqx98ipcQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp-naA-_cCrz-w81rqx98ipcQ==/lib/arm64, /system/lib64, /vendor/lib64]] 
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:379) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:312) 
... 32 more 

一些更多的信息:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    ... 
    super.onCreate(savedInstanceState); // Crashing here MainActivity.java:190 
    ... 
} 
+1

基於堆棧跟蹤,它好像FragmentManager試圖獲取初始化過程中它的一些從捆綁的內部狀態,包試圖unparcel本身,但失敗了。因爲捆綁內容以一種微妙的方式打破。你可以在Activity'onSaveInstanceState'的調用結束時發佈Activity state Bundle的內容嗎?覆蓋該方法,在返回之前設置斷點,然後從調試器(包括所有嵌套對象及其內容)複製* entire * Bundle內容並將其粘貼到某處供我們查看(Github Gist等)。特別注意SparseArrays。 – user1643723

+0

請注意,將Bundle中的錯誤放在一邊,您自己的代碼在這裏可能會有點內疚。確保你沒有以某種方式破壞Parcel數據,因爲在你自己的一個Parcelables中犯了錯誤。 – user1643723

+0

@ user1643723我試過了,但是如何從調試器中複製某些內容以列出文本格式的所有內容? – mco

回答

4

視圖狀態保存和恢復的問題。 Youtube應用程序有一個錯誤和存儲視圖狀態,其中包含來自youtube apk的類asc的實例。所以我們的應用程序無法恢復它,因爲對這個類一無所知。我的解決辦法是防止節省YoutubePlayerView視圖狀態YouTubePlayerSupportFragment明年代碼:

@Override 
public void onSaveInstanceState(Bundle bundle) { 
    super.onSaveInstanceState(bundle); 

    // disable view state saving to prevent saving states from youtube apk which cannot be restored. 
    View view = getView(); 
    if (view instanceof ViewGroup) { 
     ViewGroup viewGroup = ((ViewGroup) view); 
     for (int i = 0; i < viewGroup.getChildCount(); i++) { 
      viewGroup.getChildAt(i).setSaveFromParentEnabled(false); 
     } 
    } 
} 

此代碼應添加到您的YouTubePlayerSupportFragment子類。 此解決方案不會從捆綁軟件中刪除youtube播放器狀態。所以youtube播放器將會成功恢復。

+0

在這裏嘗試了很多不同的解決方案之後,這就是它的工作原理。謝謝! – dtrejogo

+0

謝謝!唯一的工作解決方案 – user1354784

+0

@xkor:getView()是做什麼的? – Saggy

0

顯然,這是YouTube應用的一個bug。 我建議你使用這個hack來擦除從youtube客戶端傳遞來的bundle以避免這個分析錯誤。

@Override 
public void onCreate(Bundle b) { 
    if (b != null) { 
    final ClassLoader contextCl = getClassLoader(); 
    b.setClassLoader(contextCl); 
    } 
    super.onCreate(b); 
} 

該錯誤可能是由於YouTube庫中的代碼存儲定製Parcelable狀態包(YouTube庫中的類裏面可能是由ProGuard混淆,因此奇怪的名字:

@Override 
public void onCreate(Bundle b) { 
    if (b != null) { 
     b.remove("android:fragments"); 
    } 
    super.onCreate(b); 
} 
+0

我不確定,如果可以的話。堆棧跟蹤導致'BaseBundle#unparcel',這並不意味着,在解析FragmentManager狀態之前觸發該錯誤*你的建議是否會在調用'remove'的過程中導致它早些發生? – user1643723

+0

當我查看BaseBundle源代碼時,我的意思是相同的,但事實上,它的作用就像一個魅力,沒有崩潰和日誌中的任何堆棧跟蹤。 PS之前放棄捆綁我得到了100%的概率發生此錯誤。 PSS你的類加載器設置的建議也很有趣。我會嘗試檢查它是如何工作的。 (儘管如此,我不需要這個包在我的執行) – Fitz

+0

你確定嗎?通過省略此捆綁包,您將失去所有片段,視圖和YouTube播放器庫中包含的任何狀態的保存狀態。 – user1643723

0
按照您的onCreate代碼

使用像「asc」)。

如果上述建議不起作用,沿@菲茨的建議的線條遵循和下降的狀態包。不要試圖在onCreate中搞砸(這不會起作用),而是最好重寫onSaveInstanceState以返回Bundle.EMPTY,如果您的應用程序在進行播放時暫停。


注意,有問題的錯誤是在多個方面相當棘手。如果你(或YouTube應用程序)將嵌套Bundles存儲在彼此之內,那麼也需要設置適當的ClassLoader ...有人應該告訴Google獲得一些常識,並在Bundle中使用Thread#getContextClassLoader來徹底解決這個問題。

+0

我在我的MainActivity上試過這個,沒有運氣,仍然發生同樣的崩潰。我有MainActivity,那麼帶有ViewPager的片段和ViewPager的其中一個項目就是包含YouTubePlayerSupportFragment的片段 – dtrejogo

0

我發現我工作的解決方案。在我的onCreate方法中,我收到了由於YouTube播放器中的ClassNotFoundException而引發的RuntimeException。視頻失去其狀態。按下游戲會導致重新開始。否則照常營業。

-1

我剛剛結束了使用爲我工作一個try catch塊。

try { 
    super.onCreate(savedInstanceState); 

} catch (BadParcelableException e) { 
    // Maybe put an analytic here to see if it is still being thrown. 
    // So when youtube fixes the issue in the future we can remove this 
    // ugly try catch. 
    Log.e(TAG, e.toString); 
} 
相關問題