Webview Memory leakage solution 2: webview Leakage
In this development process, webview needs to be used to display some interfaces. However, if a page is loaded with many images, the memory usage will soar. After exiting the interface, even in the destroy () method of the Activity that contains the webview, use webview. destroy (); webview = null; no effect on memory utilization. Some people say that, once webview is referenced in your xml layout, it will block the gc of memory after re-entering the Application. Including the use of MapView, sometimes causing OOM. After several twists and turns, You can see various solutions on the Internet. Here, I will share with you. However, no fundamental solution has been found so far, and there are also sdk bugs on the Internet. However, we still need to use it.
To use WebView without causing memory leakage, we should first do not define webview nodes in xml, but dynamically generate them as needed. That is, you can place a LinearLayout node similar to ViewGroup in the place where you use WebView. Then, when you want to use WebView, dynamic generation is:
WebView mWebView = new WebView(getApplicationgContext()); LinearLayout mll = findViewById(R.id.xxx); mll.addView(mWebView);
Then you must explicitly call the onDestroy () method.
protected void onDestroy() { super.onDestroy(); mWebView.removeAllViews(); mWebView.destroy()}
Note: new WebView (getApplicationgContext (); ApplicationContext must be passed in. If the Context of the Activity is passed in, the reference to the memory will be kept. Someone uses this method to solve the problem of retaining reference after the Activity is eliminated. However, you will find that if you need to open the link in WebView or the page you open has flash, you want to get a dialog in your WebView, will cause a forced type conversion error from ApplicationContext to ActivityContext, resulting in your application crash. This is because when loading flash, the system will first use your WebView as the parent control, and then draw flash on the control. He wants to find an Activity Context to draw it, but you passed in ApplicationContext. You can understand the consequences.
As a result, the experts still reference this issue after the Activity is destroyed, providing another solution: Since you cannot delete the reference for me, I will do it myself. So the following method came into being:
public void setConfigCallback(WindowManager windowManager) { try { Field field = WebView.class.getDeclaredField("mWebViewCore"); field = field.getType().getDeclaredField("mBrowserFrame"); field = field.getType().getDeclaredField("sConfigCallback"); field.setAccessible(true); Object configCallback = field.get(null); if (null == configCallback) { return; } field = field.getType().getDeclaredField("mWindowManager"); field.setAccessible(true); field.set(configCallback, windowManager); } catch(Exception e) { }}
Then, call the above method in the Activity:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setConfigCallback((WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE));} public void onDestroy() { setConfigCallback(null); super.onDestroy();}
This reflection method is indeed useful in my experiment (2.3.6). When the application memory usage is about 70 m, it will be obviously released to 50 m or 60 m, and then the release will be somewhat slow, in fact, it cannot be seen. Before using this method, it may reach 120 MB.
But !!! Our applications require a lower memory usage. Is this swollen? Cold salad? No. After a variety of confusions, we finally found the ultimate solution !!! This method is suitable for our needs. After exiting the WebView interface, the memory is quickly reclaimed. To ask what this method is, do not set it to 9999 or 8999, as long as you carefully consider the following sentence: Enable a new process for loading the WebView interface and close the process after exiting the page.
After that, do you understand?
However, when the process was killed, I encountered another problem. The methods described on the Internet were not good,
KillBackgroundProcesses (getPackageName (); for poor usage, use System. exit (0); directly exit the VM (Android creates a virtual machine for each process ). This will certainly not be tangled. Once it exits, the memory will be released. The same is true for QQ.
There is another problem that occurs when WebView is used: WebView contains a ZoomButtonsController. getSettings (). setBuiltInZoomControls (true); after this setting is enabled, the zoom control icon appears once you touch the screen. This icon will automatically disappear in a few seconds, but on the 3.0 system or above, if the icon exits the current Activity before it disappears automatically, ZoomButton will not find the attached Window and cause the program to crash, the solution is simple: Call the web in the ondestory method of the Activity. setVisibility (View. GONE); method, manually hide it, it will not crash. There will be no such crash on the system at 3.0. It's a great deal of crashes!