import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
public final class ActivityMemoryMonitor
{
private final static ReferenceQueue<Activity> referenceQueue = new ReferenceQueue<Activity>();
private final static Map<PhantomReference<Activity>, String> phantomReferenceMap = new HashMap<PhantomReference<Activity>, String>();
private final static String logFile = "activity_memory_monitor.log";
private static Timer memoryMonitorTimer = null;
public static void setActivityToMonitoringQueue(Activity activity)
{
String activityInfo = activity.toString() + "." + activity.hashCode();
phantomReferenceMap.put(new PhantomReference<Activity>(activity, referenceQueue), activityInfo);
writeLogToFile(activity, "Activity Created: " + activityInfo);
startMonitoringIfNeeded(activity.getApplicationContext());
}
private static void startMonitoringIfNeeded(Context context)
{
if (memoryMonitorTimer != null)
{
return;
}
memoryMonitorTimer = new Timer();
memoryMonitorTimer.schedule(new MemoryMonitorTask(context), 0, 2000);
}
private static synchronized void writeLogToFile(Context context, String message)
{
FileOutputStream fos = null;
BufferedOutputStream out = null;
try
{
fos = context.openFileOutput(logFile, Context.MODE_APPEND);
out = new BufferedOutputStream(fos);
String log = new Date().toString() + " " + message + "\n";
out.write(log.getBytes());
} catch (IOException e)
{
} finally
{
close(out);
close(fos);
}
}
private static void close(Closeable c)
{
if (c == null)
{
return;
}
try
{
c.close();
} catch (IOException e)
{
}
}
private static class MemoryMonitorTask extends TimerTask
{
private Context context;
MemoryMonitorTask(Context context)
{
this.context = context;
}
@Override
public void run()
{
System.gc();
Object o = ActivityMemoryMonitor.referenceQueue.poll();
if (o != null)
{
writeLogToFile(context, "GC Cllected: " + phantomReferenceMap.get(o));
phantomReferenceMap.remove(o);
}
}
}
}