使用YouTube播放器sdk播放視頻約30〜40次導致Youtube應用程序崩潰,然後由於遠程進程的死亡而從我的應用程序中引發DeadObjectException。重現步驟:使用YouTube Android播放器api發生OutOfMemoryError 1.2.2
- 發射活動並初始化YouTubePlayer
- 加載和播放視頻數秒鐘
- 發佈YouTubePlayer和退出活動
- 重複步驟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);
}
}
}
你有沒有找到這樣的解決?我試圖在我的應用程序中實現它,它從不釋放實例,導致巨大的內存泄漏。 –
@Drew我發現一個骯髒的解決方法,它的工作原理,但我永遠不會鼓勵任何人實施它。我注意到'com.google.android.youtube'進程可以通過'activityManager.killBackgroundProcesses(「com.google.android.youtube」);'來手動終止,它需要'android.permission.KILL_BACKGROUND_PROCESSES'權限並且必須在youtube播放器實例發佈。 –
我的實現是在每10個YouTube Player初始化過程中終止進程,它運行良好並通過了我的測試,但我仍然認爲手動殺死其他進程肯定是一個壞主意。此外,我還查看了崩潰統計平臺的崩潰統計數據,發現很少有用戶面臨OOM崩潰,(每週1〜2次,相比之下每天活躍用戶數量爲50k,可能與我的應用設計有關,只有很少的用戶有耐心瀏覽超過30 + VID),然後我決定忽略它。 –