本文屬于裝糊涂的豬原創,轉載請注明出處作者
背景
在自定義時鐘的時候,無意間在onDraw方法中創建對象,然后就引發了內存的肆意增長,偽代碼為
@Override
protected void onDraw(Canvas canvas) {
method();
invalidate();
}
private void method() {
Calendar calendar = Calendar.getInstance();
...
}
學習與成長
如何發現的呢?多虧了AndroidStudio的強大功能Android Monitor。為了更好的研究AS的這個集成功能新建了一個自定義view。
public class CurrentTv extends TextView {
public CurrentTv(Context context) {
this(context, null);
}
public CurrentTv(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm", Locale.getDefault());
public CurrentTv(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
setText(getCurrentText());
}
};
public void onStart(){
handler.removeCallbacks(renderRunnable);
handler.post(renderRunnable);
}
public void onStop(){
handler.removeCallbacks(renderRunnable);
}
Runnable renderRunnable = new Runnable() {
@Override
public void run() {
handler.postDelayed(renderRunnable,1000);
}
};
private String getCurrentText() {
Date curDate = new Date();
return sdf.format(curDate);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
setText(getCurrentText());
}
@Override
public void invalidate() {
if (hasWindowFocus()) {
super.invalidate();
}
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (hasWindowFocus) {
invalidate();
}
}
}
很簡單的自定義view,功能是即時在Textview上顯示當前時間,但是在onDraw中創建的對象Date。于是乎,在下面的gif中粗淺的分析了一波。首先看到的是
image.png
Allocated不斷地增長,此時點擊
image.png
開始追蹤,幾秒后,再次點擊
image.png
停止追蹤,稍等片刻就會生成報告。
image.png
同時你可以在左側Captures中查看歷史報告
image.png
整個操作流程如下:
memory.gif
參考鏈接:
Allocation Tracker