2014-08-29 2 views
0

저는 Xamarin 스튜디오를 사용하여 Android 앱을 개발하고 있습니다. 그러나 이것은 중요하지 않습니다.로컬 HTML을 사용하여 Android viewPager 메모리가 부족합니다

페이지 뷰어를 사용하여 조각을 업로드합니다 (12 자 이하). 한 디스플레이 조각에 나는 로컬 HTML 페이지를 표시하는 webView를 사용하고 왼쪽으로 스 와이프하면 webview 내용이 다음 페이지로 변경됩니다.

그래서 제 5의 frgament에서 메모리 문제는 코드에서 다른 작업을 사용하더라도 시작되었습니다.

제 질문은 : 조각을 표시하지 않을 때 조각을 '분리하는'방법이 있습니까? 그들은 내 기억에 머물러있을 수 없습니까? 모든

에 대한

덕분에이 NB 내 코드입니다 : 자바 답변뿐만 아니라 accepeted된다

protected override void OnCreate (Bundle bundle) 
    { 
     base.OnCreate (bundle); 

     SetContentView (Resource.Layout.BookView); 

     _loader = ProgressDialog.Show (this, "Loading...", "Please wait...", true); 


     //return chapters count 
     chapters = 12 //example 

     //var dp = (int)Resources.DisplayMetrics.Density; 

     _layout = FindViewById<DrawerLayout> (Resource.Id.drawer_layout); 


     _view = FindViewById<ViewPager>(Resource.Id.bView); 
     _view.SetBackgroundColor (Color.White); 

     _currentAdapter = new AwesomeFragmentAdapter (SupportFragmentManager, path, name, chapters, this, _view); 

     _view.Adapter = _currentAdapter; 
     _view.OffscreenPageLimit = chapters; 


     List<int> positions = new List<int>(); 

     _view.PageSelected += (object sender, ViewPager.PageSelectedEventArgs e) => { 

      //get details 
      var page_load = new Task (() => { 
       //return an object with the chapter details 
       _chap = object; 
      }); 
      page_load.Start(); 

      //find the webview 
      _web = (WebView)_view.FindViewWithTag(300 + e.Position); 

      WebSettings setting = _web.Settings; 
      setting.CacheMode = CacheModes.Default; 
      setting.JavaScriptEnabled = true; 
      setting.BuiltInZoomControls = true; 
      setting.DisplayZoomControls = false; 
      setting.PluginsEnabled = true; 
      setting.SetPluginState(WebSettings.PluginState.On); 
      //setting.JavaScriptCanOpenWindowsAutomatically = true; 

      if (positions.Contains(e.Position)) { 
       _web.ClearCache(true); 
       _web.ClearView(); 

      } 

     //Start when the scroll is finished 

      _view.PageScrollStateChanged += (object sendero, ViewPager.PageScrollStateChangedEventArgs ex) => { 
       if (ex.State == 0) { 
        if (positions.Contains(e.Position)) { 
         //_web.Reload(); --> doesn't work 
         //Doesn't reload the .js animations 

         _web.LoadUrl ("file://" + path + "/" + _chap.Name); 
        } else { 
         _web.LoadUrl ("file://" + path + "/" + _chap.Name); 
         positions.Add(e.Position); 
        } 
       } 
      }; 
     };  

} 



public class BWebClient : WebViewClient 
{ 
    int _position; 
    string _path; 
    Activity _parent; 
    ViewPager _pager; 
    string _chapName; 
    public BWebClient (int position, string Path, Activity Parent, ViewPager Pager, string ChapName){ 
     _position = position; 
     _parent = Parent; 
     _path = Path; 
     _pager = Pager; 
     _chapName = ChapName; 
    } 


    public override void OnPageFinished (WebView view, string url) 
    { 
     base.OnPageFinished (view, url); 
     view.ScrollTo (0, _position); 
    } 

    public override bool ShouldOverrideUrlLoading (WebView view, string url) 
    { 

     if (url.StartsWith ("navigate")) { 
      string destination = url.Substring (url.IndexOf ("navigate://") + "navigate://".Length); 
      int DestinationChapter = Int32.Parse (destination.Substring (0, destination.IndexOf("_"))); 
      int l = destination.IndexOf("_") + 1; 
      int b = destination.Length - l; 
      int DestinationPage = Int32.Parse (destination.Substring (l,b)); 



      if (DestinationPage == 0) { 
       _pager.SetCurrentItem(DestinationChapter ,true); 
       WebView _web = (WebView)_pager.FindViewWithTag(300 + DestinationChapter); 
       _web.LoadUrl ("file://" + _path + "/" + _chapName); 
      } 



     } else if (url.StartsWith ("pdf")) { 
      string file_path = System.IO.Path.Combine (_path, url.Substring (url.IndexOf ("pdf://") + "pdf://".Length)); 
      Android.Net.Uri pdfFile = Android.Net.Uri.FromFile (new Java.IO.File (file_path)); 
      Intent pdfIntent = new Intent (Intent.ActionView); 
      pdfIntent.SetDataAndType (pdfFile, "application/pdf"); 
      _parent.StartActivity (pdfIntent); 
     } 

     return true; 
    } 
} 




public class AwesomeFragmentAdapter : FragmentPagerAdapter 
{ 
    string _path; 
    string _filename; 
    int _chapters; 
    Activity _parent; 
    FileUtilities _fUtils; 
    ViewPager _pager; 

    public AwesomeFragmentAdapter (Android.Support.V4.App.FragmentManager fm, 
     string path, 
     string filename, 
     int chapters, 
     Activity parent, 
     FileUtilities FUtils, 
     ViewPager Pagers): base(fm) 
    { 
     _path = path; 
     _filename = filename; 
     _chapters = chapters; 
     _parent = parent; 
     _fUtils = FUtils; 
     _pager = Pagers; 
    } 

    public override int Count 
    { 
     /* --- return chapter count --- */ 
     get { return _chapters;} 
    } 


    public override Android.Support.V4.App.Fragment GetItem(int _position) 
    { 
     /* --- get specific item --- */ 
     return new AwesomeFragment (_path, _filename, _position, _parent, _fUtils, _pager); 
    } 
} 

public class AwesomeFragment : Android.Support.V4.App.Fragment 
{ 
    string _path; 
    WebView web_view; 
    string _filename; 
    int _position; 
    Activity _parent; 
    BanjiChapter _chap; 
    FileUtilities _fUtils; 
    ViewPager _pager; 

    public AwesomeFragment() {} 

    public AwesomeFragment (string path, 
     string filename, 
     int position, 
     Activity parent, 
     FileUtilities FUtils, 
     ViewPager Pager) 
    { 
     _path = path; 
     _filename = filename; 
     _position = position; 
     _parent = parent; 
     _fUtils = FUtils; 
     _pager = Pager; 
    } 

    public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     /* --- Create the view --- */ 
     var view = inflater.Inflate (Resource.Layout.BookWebView, container, false); 

    //return the chapter 
     _chap = _fUtils.ReturnChapterDetails(_filename, _position); 

     web_view = view.FindViewById<WebView> (Resource.Id.webview); 


     web_view.SetWebViewClient(new BanjiWebClient(_position,_path,_parent, _pager, _chap.Name)); 



     web_view.SetBackgroundColor(Color.Transparent); 
     web_view.Settings.JavaScriptEnabled = true; 
     web_view.Tag = 300 + _position; 

     switch(Resources.DisplayMetrics.DensityDpi){ 
      case Android.Util.DisplayMetricsDensity.Medium: 
       { 
        web_view.SetLayerType (LayerType.Software, null); 
        break; 
       } 
      case Android.Util.DisplayMetricsDensity.High: 
       { 
        web_view.SetLayerType (LayerType.Hardware, null); 
        break; 
       } 
      case Android.Util.DisplayMetricsDensity.Xhigh: 
       { 
        web_view.SetLayerType (LayerType.Hardware, null); 
        break; 
       } 
      } 




     if (_chap.Background == null) { 
      view.SetBackgroundColor (Color.White); 
     } else { 
      view.SetBackgroundDrawable (new BitmapDrawable (BitmapFactory.DecodeByteArray (_chap.Background, 0, _chap.Background.Length))); 
     } 

     if (_position == 0) { 
      web_view.LoadUrl ("file://" + _path + "/" + _chap.Name); 
     } 

     return view; 

    } 

    public BChapter GetCurrentBChapter() 
    { 
     return _chap; 
    } 

}  

편집 :

BookView.axml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/drawer_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#ffececec"> 
<!-- The main content view --> 
    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/mainView"> 
     <android.support.v4.view.ViewPager 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:id="@+id/bookView" /> 
     <ImageButton 
      android:layout_height="wrap_content" 
      android:layout_width="wrap_content" 
      android:layout_gravity="left|center" 
      android:background="@null" 
      android:id="@+id/menuButton" 
      /> 
    </FrameLayout> 
<!-- The navigation drawer --> 
    <LinearLayout 
     android:id="@+id/left_menu" 
     android:layout_width="250dp" 
     android:layout_height="match_parent" 
     android:choiceMode="singleChoice" 
     android:layout_gravity="start" 
     android:divider="@android:color/transparent" 
     android:dividerHeight="0dp" 
     android:background="#111"> 
     <Button 
      android:id="@+id/backStep" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      style="@style/button_text" 
      android:background="#ff000000" 
      android:fitsSystemWindows="false" /> 
     <Space 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" /> 
     <ScrollView 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:id="@+id/screllArea"> 
      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:id="@+id/ThumbLayout" /> 
     </ScrollView> 
    </LinearLayout> 
</android.support.v4.widget.DrawerLayout> 

BookWebView

<?xml version="1.0" encoding="utf-8"?> 
<WebView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/webview" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

답변

1

대신 FragmentStatePagerAdapter을 사용하십시오. 프래그먼트가 표시되지 않을 때 프래그먼트를 파기하여 메모리 오버 헤드를 최소화하도록 설계되어 해당 프래그먼트의 상태 정보 만 저장합니다. 개발자의 문서에서

:

This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to FragmentPagerAdapter at the cost of potentially more overhead when switching between pages.

See here for documentation.

+0

감사 남자, 내가 시도거야! – BlackShawarna

+0

아뇨, 불행히도 메모리 문제는 여전히 존재합니다. – BlackShawarna

+0

BookView 레이아웃에 대한 코드를 포함 할 수 있습니까? 레이아웃 파일이 유출되어 WebView가 생성되는 문제가 계속 발생했습니다. http://stackoverflow.com/questions/3130654/memory-leak-in-webview – matthewrdev

관련 문제