I am so sorry if this is duplicate question, I googled for 1 day but still not find the desired solution. Because I want to preserve all state of WebView (javascript environment, display pages...), I declare my webview in application class as below
public class RAPINaviMainApplication extends Application {
private WebView mWebView = null;
private boolean isWebViewInitialized = false;
@Override
public void onCreate () {
super.onCreate();
mWebView = new WebView(getApplicationContext());
isWebViewInitialized = false; // we do some initialization once in our activity.
mWebView.setWebViewClient(new WebViewClient());
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mWebView.getSettings().setJavaScriptEnabled(true);
}
public boolean isWebViewInitialized() {
return isWebViewInitialized;
}
public void setWebViewInitialized(boolean initialize) {
isWebViewInitialized = initialize;
}
public WebView getWebView() {
return mWebView;
}
}
And then I add webview in a RAPINaviMainFragment dynamically to display its content when user choose the fragment in Naviagtion Drawer (Android Navigation Drawer template) as below
public class RAPINaviMainFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
private static final String TAG = "RAPINaviMainFragment";
private FrameLayout mFrameLayout;
public static RAPINaviMainFragment newInstance(int sectionNumber) {
RAPINaviMainFragment fragment = new RAPINaviMainFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public RAPINaviMainFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_rapinavi_main, container,
false);
mFrameLayout = (FrameLayout) rootView.findViewById(R.id.webview_container);
if (((RAPINaviMainApplication)getActivity().getApplication()).isWebViewInitialized() == false) {
((RAPINaviMainApplication)getActivity().getApplication()).getWebView().loadUrl("http://www.google.com");
((RAPINaviMainApplication)getActivity().getApplication()).setWebViewInitialized(true);
}
return rootView;
}
@Override
public void onAttach(Activity activity) {
Log.i(TAG, getClass().getSimpleName() + ":entered onAttach()");
super.onAttach(activity);
((RAPINaviMainActivity) activity).onSectionAttached(getArguments()
.getInt(ARG_SECTION_NUMBER));
}
@Override
public void onResume() {
Log.i(TAG, getClass().getSimpleName() + ":entered onResume()");
super.onResume();
mFrameLayout.addView(((RAPINaviMainApplication)getActivity().getApplication()).getWebView());
}
@Override
public void onPause() {
Log.i(TAG, getClass().getSimpleName() + ":entered onPause()");
super.onPause();
mFrameLayout.removeView(((RAPINaviMainApplication)getActivity().getApplication()).getWebView());
}
}
The problem is that, whenver user switch from other Fragment to RAPINaviMainFragment (by selecting item in Naviation Drawer) or when user load a new website in webview, I receive the memory leak information from logcat
07-26 14:11:31.371: I/dalvikvm-heap(10391): Grow heap (frag case) to 12.937MB for 6317296-byte allocation
07-26 14:11:34.825: I/RAPINaviMainFragment(10391): RAPINaviMainFragment:entered onPause()
07-26 14:11:37.578: I/RAPINaviMainFragment(10391): RAPINaviMainFragment:entered onAttach()
07-26 14:11:37.578: I/RAPINaviMainFragment(10391): RAPINaviMainFragment:entered onResume()
07-26 14:11:37.618: I/dalvikvm-heap(10391): Grow heap (frag case) to 12.936MB for 6317296-byte allocation
07-26 14:12:42.167: I/RAPINaviMainFragment(10391): RAPINaviMainFragment:entered onPause()
I also set follow option in AndroidManifest.xml
android:largeHeap="true"
When I commented addView() and removeView() action from FrameLayout, there was no memory leak. I also tried to use WeakReference to WebView RAPINaviApplication but the issue still occurs. I am really appreciate if anyone know the root of this problem and give me the solution to solve it.
0 comments:
Post a Comment