Intereting Posts
Папка projectFilesBackup в проекте студии Android для последней версии Пользовательская «клавиатура», встроенная в приложение на Android Android: Круговой кружок MapView с динамическим радиусом (в метрах) Как заставить производный класс вызвать супер метод? (Как и Android) Тесты Robolectric, работающие в Android Studio, но не в командной строке Android ADT Eclipse плагин, parseSDKContent не удалось Как отображать изображения, сохраненные в папке sdcard в android Android EditText («Текстовое поле»): автоматическая заливка первой буквы каждого слова во время ввода пользователем Выравнивание фрагментов с помощью RelativeLayout Отображение профиля профиля FB в виде кругового изображения в приложении Планировщики по умолчанию для rxjava на Android Скриншот Android-эмулятора от Android Studio 0.9.2 Как получить захват экрана при двойном разрешении? Пользовательская кнопка с выдвижным фоном: разница в разнице в Android 4 и Android 2.3 Есть ли разница между Java и Java Oracle, используемыми в Android?

Через некоторое время мое приложение зависает во время прокрутки WebView, говоря «не удалось заблокировать поверхность»,

Мое Android-приложение состоит из нескольких действий, каждый из которых отвечает за один фрагмент (пока). Мои фрагменты обычно отображаются / прикрепляются несколько так:

mTopicFragment = (TopicFragment)getSupportFragmentManager().findFragmentByTag("topic"); if(mTopicFragment == null) mTopicFragment = TopicFragment.newInstance(bid, page, pid); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.content, mTopicFragment, "topic") .commit(); } 

TopicFragment содержит WebView отображающий некоторые материалы HTML и CSS / JS. После некоторого времени просмотра приложения прокрутка в одном из этих TopicFragment объектов TopicFragment становится медленной, и в конечном итоге приложение полностью замораживается. В журнале ADB указано следующее исключение:

 12-12 22:49:33.931 12582-12582/com.mde.potdroid3 W/Adreno-EGLSUB﹕ <DequeueBuffer:606>: dequeue native buffer fail: Unknown error 2147483646, buffer=0x0, handle=0x0 12-12 22:49:33.941 12582-12582/com.mde.potdroid3 W/Adreno-EGLSUB﹕ <DequeueBuffer:606>: dequeue native buffer fail: Invalid argument, buffer=0x0, handle=0x0 12-12 22:49:33.941 12582-12582/com.mde.potdroid3 W/Adreno-ES20﹕ <gl2_surface_swap:43>: GL_OUT_OF_MEMORY 12-12 22:49:33.941 12582-12582/com.mde.potdroid3 W/Adreno-EGL﹕ <qeglDrvAPI_eglSwapBuffers:3597>: EGL_BAD_SURFACE 12-12 22:49:33.941 12582-12582/com.mde.potdroid3 W/HardwareRenderer﹕ EGL error: EGL_BAD_SURFACE 12-12 22:49:33.951 12582-12582/com.mde.potdroid3 W/HardwareRenderer﹕ Mountain View, we've had a problem here. Switching back to software rendering. 12-12 22:20:04.461 10081-10081/com.mde.potdroid3 E/Surface﹕ dequeueBuffer failed (Unknown error 2147483646) 12-12 22:20:04.461 10081-10081/com.mde.potdroid3 E/ViewRootImpl﹕ Could not lock surface java.lang.IllegalArgumentException at android.view.Surface.nativeLockCanvas(Native Method) at android.view.Surface.lockCanvas(Surface.java:243) at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2435) at android.view.ViewRootImpl.draw(ViewRootImpl.java:2409) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2253) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1883) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761) at android.view.Choreographer.doCallbacks(Choreographer.java:574) at android.view.Choreographer.doFrame(Choreographer.java:544) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5081) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 

В Интернете я могу найти информацию об этом исключении, где у людей есть свои пользовательские представления. Что здесь происходит? Может ли это быть связано с потреблением памяти моего приложения? Кажется, что каждый раз, когда я вызываю код выше, новый экземпляр TopicFragment , отображается и TopicFragment в задний стек. Как я могу отладить это поведение?


Еще одна информация: приложение, похоже, использует много CPU, когда я включаю оверлей в настройках разработчика. Может быть, мои фрагменты не отделяются должным образом, когда я их оставляю и почему-то продолжаю работать в фоновом режиме?


Вот как я использую WebView:

 mWebView = (WebView)getView().findViewById(R.id.topic_webview); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.getSettings().setDomStorageEnabled(true); mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); mWebView.getSettings().setAllowFileAccess(true); mWebView.addJavascriptInterface(mJsInterface, "api"); mWebView.setWebChromeClient(new WebChromeClient()); mWebView.loadData("", "text/html", "utf-8"); mWebView.setBackgroundColor(0x00000000); 

Здесь не упоминается утечка памяти.

Solutions Collecting From Web of "Через некоторое время мое приложение зависает во время прокрутки WebView, говоря «не удалось заблокировать поверхность»,"

Думаю, я это исправил. По-видимому, есть ошибка, которая предотвращает правильное управление памятью WebView. Когда я запускаю много видов деятельности с помощью WebView в своих представлениях, WebViews живут в памяти, а действия не будут надлежащим образом убиты, когда память работает на низком уровне. Я работал над этой проблемой со следующим кодом в моем TopicFragment который отображает WebView :

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) { View v = super.onCreateView(inflater, container, saved); mActivity = (BaseActivity) getSupportActivity(); // this is the framelayout which will contain our WebView mWebContainer = (FrameLayout) v.findViewById(R.id.web_container); return v; } public void onResume() { super.onResume(); // create new WebView and set all its options. mWebView = new WebView(mActivity); mWebView.... // add it to the container mWebContainer.addView(mWebView); // if data is available, display it immediately if(mTopic != null) { mWebView.loadDataWithBaseURL("file:///android_asset/", mTopic.getHtmlCache(), "text/html", "UTF-8", null); } } @Override public void onPause() { super.onPause(); // destroy the webview mWebView.destroy(); mWebView = null; // remove the view from the container. mWebContainer.removeAllViews(); } 

Таким образом, WebView создается и удаляется в onResume и onPause . Это некоторые накладные расходы и не совершенны, но он решает проблему памяти и едва заметен с точки зрения производительности и т. Д.

Если у вас много WebViews в приложении в разных действиях / фрагментах, вы можете попытаться использовать пул, в котором вы можете получить экземпляр WebView в методе Activies onCreate () и вернуть WebView в пул в Activies onDestory ().

Размер WebViewPool можно настроить с помощью класса памяти устройств пользователей. Это не может быть лучшим решением для каждого приложения, использующего веб-просмотры, но это решение, которое вы можете рассмотреть. Возможно, вам понадобится тестирование и т. Д.

Но имейте в виду, что объекты в пуле не собирают мусор, поэтому будьте осторожны, если вы решите использовать пул.

Наконец я нашел проблему. Отключение аппаратного ускорения для WebView решает его.

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) { //... if (Utils.isKitkat()) { disableHardwareAcc(); } //... } @TargetApi(Build.VERSION_CODES.HONEYCOMB) protected void disableHardwareAcc() { mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); }