import android.app.Activity;
import android.app.Application;
import android.app.Application.ActivityLifecycleCallbacks;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import java.lang.ref.WeakReference;
/**
* 内存泄露自动监测。
* 监测Activity泄露:
* 在Application的onCreate()方法中调用 MemoryWatcher.install(Application.this, null);
* 监测普通对象泄露:
* 对象使用完毕后调用 MemoryWatcher.watch(object);
*/
public class MemoryWatcher {
public static final String TAG = "MemoryWatcher";
private static final int MSG_CHECK_1 = 1;
private static final int MSG_CHECK_2 = 2;
private static final long DELAY_CHECK_1 = 1000;
private static final long DELAY_CHECK_2 = 210 * 1000;
private static Handler handler = null;
private static Context context = null;
private static LeakCallback callback = null;
public static void install(Application app) {
app.registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks());
context = app.getApplicationContext();
}
public static void install(Application app, LeakCallback callback) {
app.registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks());
context = app.getApplicationContext();
MemoryWatcher.callback = callback;
}
public static void watch(Object object) {
synchronized (MemoryWatchHandler.class) {
if (handler == null) {
// thread will don't quit
HandlerThread thread = new HandlerThread(TAG);
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
handler = new MemoryWatchHandler(thread.getLooper());
}
if (callback == null) {
callback = new LogLeakCallback();
}
}
WatchObject wObj = new WatchObject(object);
Message msg = handler.obtainMessage(MSG_CHECK_1, wObj);
handler.sendMessageDelayed(msg, DELAY_CHECK_1);
}
private static void gc() {
System.gc();
System.runFinalization();
System.gc();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// do nothing
}
}
public interface LeakCallback {
/**
* 被监测对象立即被释放
*/
void free(Context context, WatchObject obj);
/**
* 被监测对象没有立即被释放,可能存在泄露
*/
void mayLeak(Context context, WatchObject obj);
/**
* 被监测对象在数分钟之后才被释放,可能存在一些问题
*/
void freeLater(Context context, WatchObject obj);
/**
* 被检测对象在数分钟之后还没有被释放,很可能是已泄露
*/
void leak(Context context, WatchObject obj);
}
private static class LogLeakCallback implements LeakCallback {
@Override
public void free(Context context, WatchObject wObj) {
LogUtil.d(true, TAG, wObj.name, " freed!");
}
@Override
public void mayLeak(Context context, WatchObject wObj) {
LogUtil.e(true, TAG, wObj.name, " may leaked!");
}
@Override
public void freeLater(Context context, WatchObject wObj) {
LogUtil.d(true, TAG, wObj.name, " freed later!");
}
@Override
public void leak(Context context, WatchObject wObj) {
LogUtil.e(true, TAG, wObj.name, " leaked!");
}
}
private static class MyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivityDestroyed(Activity activity) {
watch(activity);
}
}
public static final class WatchObject {
private WeakReference<Object> ref;
private String name;
public WatchObject(Object obj) {
ref = new WeakReference<Object>(obj);
name = obj.toString();
}
public Object get() {
return ref.get();
}
@Override
public String toString() {
return name;
}
}
private static class MemoryWatchHandler extends Handler {
public MemoryWatchHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
if (null == msg) {
return;
}
switch (msg.what) {
case MSG_CHECK_1: {
gc();
if (null == msg.obj || !(msg.obj instanceof WatchObject)) {
break;
}
WatchObject wObj = (WatchObject) msg.obj;
if (wObj.get() != null) {
callback.mayLeak(context, wObj);
Message m = handler.obtainMessage(MSG_CHECK_2, wObj);
handler.sendMessageDelayed(m, DELAY_CHECK_2);
} else {
callback.free(context, wObj);
}
}
break;
case MSG_CHECK_2: {
gc();
if (null == msg.obj || !(msg.obj instanceof WatchObject)) {
break;
}
WatchObject wObj = (WatchObject) msg.obj;
if (wObj.get() != null) {
callback.leak(context, wObj);
} else {
callback.freeLater(context, wObj);
}
}
break;
default:
break;
}
}
}
}
AndroidUtil - 极简内存泄漏监控 - 结合弱引用和组件生命周期
猜你喜欢
转载自blog.csdn.net/qq_16206535/article/details/79448215
今日推荐
周排行