2016-08-23 57 views
3

使用YouTube播放器sdk播放視頻約30〜40次導致Youtube應用程序崩潰,然後由於遠程進程的死亡而從我的應用程序中引發DeadObjectException。重現步驟:使用YouTube Android播放器api發生OutOfMemoryError 1.2.2

  1. 發射活動並初始化YouTubePlayer
  2. 加載和播放視頻數秒鐘
  3. 發佈YouTubePlayer和退出活動
  4. 重複步驟1-3約爲30〜40倍

的OutOfMemoryError日誌(full logs):

08-22 12:01:01.461 E/AndroidRuntime(3017): FATAL EXCEPTION: main 
08-22 12:01:01.461 E/AndroidRuntime(3017): Process: com.google.android.youtube.player, PID: 3017 
08-22 12:01:01.461 E/AndroidRuntime(3017): java.lang.OutOfMemoryError: Could not allocate JNI Env 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at java.lang.Thread.nativeCreate(Native Method) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at java.lang.Thread.start(Thread.java:1063) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:921) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1556) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:310) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:527) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at java.util.concurrent.ScheduledThreadPoolExecutor.execute(ScheduledThreadPoolExecutor.java:616) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at reo.a(SourceFile:134) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at sgh.a(SourceFile:722) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at gan.a(SourceFile:310) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at gan.b(SourceFile:338) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at com.google.android.apps.youtube.embeddedplayer.service.service.jar.ApiPlayerService$2.run(SourceFile:215) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at android.os.Handler.handleCallback(Handler.java:739) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at android.os.Handler.dispatchMessage(Handler.java:95) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at android.os.Looper.loop(Looper.java:148) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at android.app.ActivityThread.main(ActivityThread.java:5417) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at java.lang.reflect.Method.invoke(Native Method) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
08-22 12:01:01.461 E/AndroidRuntime(3017):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

和DeadObjectException

08-22 12:01:01.842 E/MonitoringInstrumentation(2976): java.lang.IllegalStateException: android.os.DeadObjectException 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at gix.surfaceCreated(SourceFile:189) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.SurfaceView.updateWindow(SurfaceView.java:582) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2055) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.Choreographer.doCallbacks(Choreographer.java:670) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.Choreographer.doFrame(Choreographer.java:606) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.os.Handler.handleCallback(Handler.java:739) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.os.Handler.dispatchMessage(Handler.java:95) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.os.Looper.loop(Looper.java:148) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.app.ActivityThread.main(ActivityThread.java:5417) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at java.lang.reflect.Method.invoke(Native Method) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): Caused by: android.os.DeadObjectException 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.os.BinderProxy.transactNative(Native Method) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at android.os.BinderProxy.transact(Binder.java:503) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at com.google.android.apps.youtube.embeddedplayer.service.service.jar.ISurfaceHolderService$Stub$Proxy.a(SourceFile:110) 
08-22 12:01:01.842 E/MonitoringInstrumentation(2976): at gix.surfaceCreated(SourceFile:186) 

YouTube應用版本是55年11月29日,Nexus 5的仿真器與棉花糖 ,我已經像57年10月25日和10.40.58 YouTube應用其它版本測試它的OOM仍然出現。

剛開始的時候我遇到這個問題,我以爲這只是一些不正確的api方法調用引起的,但經過這麼多小時的調查後,我發現它應該是一個YouTube應用的問題,希望有人能幫我解決它,或者至少避免它。

進程com.google.android.youtube.player的內存不斷增加,而內存監視器播放器初始化和視頻播放,以及許多YoutubeService實例已創建但未從轉儲文件中回收。任何想法?

我基於官方YouTubeAndroidAPI樣品和內存不足錯誤演示應用程序進行測試時,以及,我只是在PlayerViewDemoActivity取代cueVideo(String)通過loadVideo(String)爲自動播放,並在onDestroy()添加YouTubePlayer#release(),我也加入了測試代碼基於Espresso重現內存泄漏問題。

這裏是測試代碼,here是完整的演示代碼。

package com.examples.youtubeapidemo.play; 

import android.os.SystemClock; 
import android.support.test.rule.ActivityTestRule; 
import android.support.test.runner.AndroidJUnit4; 
import android.test.suitebuilder.annotation.LargeTest; 
import android.util.Log; 

import com.examples.youtubeapidemo.YouTubeAPIDemoActivity; 

import org.junit.Rule; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

import static android.support.test.espresso.Espresso.onView; 
import static android.support.test.espresso.Espresso.pressBack; 
import static android.support.test.espresso.action.ViewActions.click; 
import static android.support.test.espresso.matcher.ViewMatchers.withText; 

/** 
* for YouTubePlayerView testing 
*/ 
@RunWith(AndroidJUnit4.class) 
@LargeTest 
public class PlayerViewTest { 

    @Rule 
    public ActivityTestRule<YouTubeAPIDemoActivity> mActivityTestRule = 
      new ActivityTestRule<YouTubeAPIDemoActivity>(YouTubeAPIDemoActivity.class); 

    @Test 
    public void testYouTubeMemoryLeaks() { 
     int count = 0; 
     while(count < 100) { 
      onView(withText("Simple PlayerView")).perform(click()); 
      SystemClock.sleep(10000); // waiting for video start playing 
      pressBack(); 
      count++; 
      Log.i("PlayerViewTest", "count: " + count); 
     } 
    } 
} 
+0

你有沒有找到這樣的解決?我試圖在我的應用程序中實現它,它從不釋放實例,導致巨大的內存泄漏。 –

+1

@Drew我發現一個骯髒的解決方法,它的工作原理,但我永遠不會鼓勵任何人實施它。我注意到'com.google.android.youtube'進程可以通過'activityManager.killBackgroundProcesses(「com.google.android.youtube」);'來手動終止,它需要'android.permission.KILL_BACKGROUND_PROCESSES'權限並且必須在youtube播放器實例發佈。 –

+1

我的實現是在每10個YouTube Player初始化過程中終止進程,它運行良好並通過了我的測試,但我仍然認爲手動殺死其他進程肯定是一個壞主意。此外,我還查看了崩潰統計平臺的崩潰統計數據,發現很少有用戶面臨OOM崩潰,(每週1〜2次,相比之下每天活躍用戶數量爲50k,可能與我的應用設計有關,只有很少的用戶有耐心瀏覽超過30 + VID),然後我決定忽略它。 –

回答

0

我通過把YouTube的調用(如youtubePlayer.loadVideo(),cueVideo(),getCurrentTimeMillis()等)在try catch塊,趕上然後IllegalStateException異常例外重新初始化YouTube播放器,減少了錯誤的發生。

和工作圍繞它通過捕獲這些異常並重新啓動活動,

看到這個線程我的回答: Getting a lot of crashes from android youtube player api

相關問題