Created
February 22, 2014 11:18
-
-
Save SeanZoR/9152254 to your computer and use it in GitHub Desktop.
Android - Remove Binding helper - When you want to finish Activity w/o leaks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class UnbindingHelper { | |
/** | |
* Removes the reference to the activity from every view in a view hierarchy (listeners, | |
* images etc.). | |
* This method should be called in the onDestroy() method of each activity | |
* | |
* @param viewID normally the id of the root layout | |
* <p/> | |
* see http://code.google.com/p/android/issues/detail?id=8488 | |
*/ | |
@SuppressWarnings("SameParameterValue") | |
public static void unbindReferences(Activity activity, int viewID) { | |
try { | |
View view = activity.findViewById(viewID); | |
if (view != null) { | |
unbindViewReferences(view); | |
if (view instanceof ViewGroup) { | |
unbindViewGroupReferences((ViewGroup) view); | |
} | |
} | |
System.gc(); | |
} catch (Throwable e) { | |
// whatever exception is thrown just ignore it because a crash is always worse | |
// than this method not doing what it's supposed to do | |
} | |
} | |
@SuppressWarnings("EmptyCatchBlock") // If this fails, it's ok, it's a (very) nice to have, that's all | |
private static void unbindViewGroupReferences(ViewGroup viewGroup) { | |
for (int i = 0; i < viewGroup.getChildCount(); i++) { | |
View view = viewGroup.getChildAt(i); | |
unbindViewReferences(view); | |
if (view instanceof ViewGroup) { | |
unbindViewGroupReferences((ViewGroup) view); | |
} | |
} | |
try { | |
viewGroup.removeAllViews(); | |
} catch (Throwable mayHappen) { | |
// AdapterViews, ListViews and potentially other ViewGroups don't support the | |
// removeAllViews operation | |
} | |
} | |
@SuppressWarnings({"EmptyCatchBlock", "deprecation"}) | |
// If this fails, it's ok, it's a (very) nice to have, that's all | |
private static void unbindViewReferences(View view) { | |
// set all listeners to null (not every view and not every API level supports the | |
// methods) | |
try { | |
view.setOnClickListener(null); | |
} catch (Throwable mayHappen) { | |
} | |
try { | |
view.setOnCreateContextMenuListener(null); | |
} catch (Throwable mayHappen) { | |
} | |
try { | |
view.setOnFocusChangeListener(null); | |
} catch (Throwable mayHappen) { | |
} | |
try { | |
view.setOnKeyListener(null); | |
} catch (Throwable mayHappen) { | |
} | |
try { | |
view.setOnLongClickListener(null); | |
} catch (Throwable mayHappen) { | |
} | |
try { | |
view.setOnClickListener(null); | |
} catch (Throwable mayHappen) { | |
} | |
// set background to null | |
Drawable d = view.getBackground(); | |
if (d != null) { | |
d.setCallback(null); | |
} | |
if (view instanceof ImageView) { | |
ImageView imageView = (ImageView) view; | |
d = imageView.getDrawable(); | |
if (d != null) { | |
d.setCallback(null); | |
} | |
imageView.setImageDrawable(null); | |
imageView.setBackgroundDrawable(null); | |
imageView.setImageBitmap(null); | |
} | |
// destroy webview | |
if (view instanceof WebView) { | |
view.destroyDrawingCache(); | |
((WebView) view).destroy(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment