打算写一个系列吧,包括程序怎么优化,如何避免内存泄露,出现内存泄露该如何处理分析。
这个系列应该会很长,首先会根据实际项目中遇到的东西总结整理上来,然后会收集网上相关好资源分享。
内容大致分两种,一种是[实战N]开头,都是可以直接拿来用的,可能比较少甚至没有理论内容。
另一种以初步拟定以[理论/原理N]开头,会解释介绍一些内存泄露,javaGC原理等内容。使大家知其然知其所以然。
当然希望大家看后有疑问、不同观点等尽量及时指出,多多交流。
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' // or 1.4-beta2 releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta2 testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta2
public static RefWatcher getRefWatcher(Context context) { LeakDemoApplication application = (LeakDemoApplication) context.getApplicationContext(); return application.refWatcher; } private RefWatcher refWatcher; @Override public void onCreate() { super.onCreate(); refWatcher = LeakCanary.install(this); }即在Application的onCreate()方法里,调用LeakCanary.install(this)方法,得到方法返回的RefWatcher对象,用于给其他Activity监控内存泄露使用。
@Override protected void onDestroy() { super.onDestroy(); /** * 在Activity的onDestroy()里添加如下代码即可对该Activity的内存泄露问题进行监控。 * 一般我们的项目都会有一个BaseActivity,在BaseActivity里onDestroy()方法里添加如下代码即可监控该App所有的Activity的内存泄露问题。 */ RefWatcher refWatcher = LeakDemoApplication.getRefWatcher(this); refWatcher.watch(this); }3.2,如果是Fragment的话:
@Override public void onDestroy() { super.onDestroy(); RefWatcher refWatcher = LeakDemoApplication.getRefWatcher(getActivity()); refWatcher.watch(this); }他们监控的都是Activity.
package mcxtzhang.leakdemo; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Toast; import com.squareup.leakcanary.RefWatcher; /** * Created by zhangxutong . * Date: 16/03/29 */ public class LeakActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_leak); } @Override protected void onDestroy() { super.onDestroy(); /** * 在Activity的onDestroy()里添加如下代码即可对该Activity的内存泄露问题进行监控。 * 一般我们的项目都会有一个BaseActivity,在BaseActivity里onDestroy()方法里添加如下代码即可监控该App所有的Activity的内存泄露问题。 */ RefWatcher refWatcher = LeakDemoApplication.getRefWatcher(this); refWatcher.watch(this); /** * 非静态内部类Handler内存泄露解决方法: */ if(mLeakHandler.hasMessages(MSG_LEAK_DELAY)){ mLeakHandler.removeMessages(MSG_LEAK_DELAY); } //或者使用如下语句,移除所有此Handler里未被执行的CallBack和Message //mLeakHandler.removeCallbacksAndMessages(null); } /** * 下面的是一个典型的内存泄露实例: * 即一个非静态内部类Handler中有未来得及处理或者延时处理的消息, * 但是此时该Activity退出了,并没有移除Handler中未处理的消息,会造成内存泄露。 * 解决方法是, * 一:将此Handler改写为静态内部类,并使用WeakReference弱引用来引用Activity对象。 * 二(推荐):在Activity的onDestroy()方法里移除未处理的消息。 * 原因是:非静态内部类会持有外部类的引用: * 持有关系大致为:Looper-MessageQueue-Message-Handler-Activity */ private static final int MSG_LEAK_DELAY = 1; private Handler mLeakHandler = new Handler() { @Override public void handleMessage(Message msg) { //do sth Log.d("zxt", "handleMessage() called with: " + "msg = [" + msg + "]"); } }; public void onLeakClick(View v) { Toast.makeText(this, "已经成功产生一个内存泄露,现在退出此Activity试试看。", Toast.LENGTH_SHORT).show(); mLeakHandler.sendEmptyMessageDelayed(MSG_LEAK_DELAY, 1000000); } }