1. 数据库Cursor没关。
    当我们操作完数据库后,一定要调用close()释放资源。

  2. 构造Adapter没有使用缓存ContentView

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder vHolder = null;
    //如果convertView对象为空则创建新对象,不为空则复用
    if (convertView == null) {
    convertView = inflater.inflate(..., null);
    // 创建 ViewHodler 对象
    vHolder = new ViewHolder();
    vHolder.img= (ImageView) convertView.findViewById(...);
    vHolder.tv= (TextView) convertView
    .findViewById(...);
    // 将ViewHodler保存到Tag中
    convertView.setTag(vHolder);
    } else {
    //当convertView不为空时,通过getTag()得到View
    vHolder = (ViewHolder) convertView.getTag();
    }
    // 给对象赋值,修改显示的值
    vHolder.img.setImageBitmap(...);
    vHolder.tv.setText(...);
    return convertView;
    } static class ViewHolder {
    TextView tv;
    ImageView img;
    }
  3. 未取消注册广播接收者
    registerReceiver()unregisterReceiver()要成对出现,通常需要在ActivityonDestory()方法去取消注册广播接收者。

  4. IO流未关闭 注意用完后及时关闭

  5. Bitmap使用后未调用recycle()

  6. Context泄漏 这是一个很隐晦的OutOfMemoryError的情况。先看一个Android官网提供的例子:

    private static Drawable sBackground;
    @Override
    protected void onCreate(Bundle state) {
    super.onCreate(state);
    TextView label = new TextView(this);
    label.setText("Leaks are bad");
    if (sBackground == null) {
    sBackground = getDrawable(R.drawable.large_bitmap);
    }
    label.setBackgroundDrawable(sBackground);
    setContentView(label);
    }

    这段代码效率很快,但同时又是极其错误的:
    我们看一下setBackgroundDrawable(Drawable background)的源码:

    public void setBackgroundDrawable(Drawable background) {
    ...
    background.setCallback(this);
    }

    background.setCallback(this);方法,也就是说Drawable拥有TextView的引用,而TextView又拥有Activity(Context类型)的引用, 因为sBackgroundstatic的,即使Activity被销毁,但是sBackground的生命周期还没走完,所以内存仍然不会被释放。这样就会有内存泄露了。 对,这样想是对的,但是我们看一下setCallback的源码:

    public final void setCallback(Callback cb) {
    mCallback = new WeakReference<Callback>(cb);
    }

    我们会发现里面使用了WeakReference,所以不会存在内存泄露了,但是官网当时提供的例子明明说有泄露,这是因为在3.0之后, 修复了这个内存泄露的问题,在3.0之前setCallback,方法是没有使用WeakReference的,所以这种泄露的情况在3.0之前会发生,3.0之后已经被修复。

  7. 线程 线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。我们来考虑下面一段代码。

    public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    new MyThread().start();
    }
    private class MyThread extends Thread{
    @Override
    public void run() {
    super.run();
    //耗时的操作
    }
    }
    }

    假设MyThreadrun函数是一个很费时的操作,当调用finish的时候Activity会销毁掉吗?
    事实上由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThreadrun函数没有结束时,MyThread是不会被销毁的, 因此它所引用的Activity也不会被销毁,因此就出现了内存泄露的问题。

  8. 尽量使用ApplicationContext Context引用的生命周期超过它本身的生命周期,也会导致Context泄漏。 所以如果打算保存一个长时间的对象时尽量使用Application这种Context类型。 例如:

    mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
    改成:
    mStorageManager = (StorageManager) getApplicationContext().getSystemService(Context.STORAGE_SERVICE);

    按道理来说这种系统服务是不会有问题,但是有些厂商在修改的时候,可能会导致Context无法被及时释放。

  9. Handler的使用,在Activity退出的时候注意移除(尤其是循环的时候)

    public class ThreadDemo extends Activity {
    private static final String TAG = "ThreadDemo";
    private int count = 0;
    private Handler mHandler = new Handler(); private Runnable mRunnable = new Runnable() { public void run() {
    //为了方便 查看,我们用Log打印出来
    Log.e(TAG, Thread.currentThread().getName() + " " +count);
    //每2秒执行一次
    mHandler.postDelayed(mRunnable, 2000);
    }
    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    //通过Handler启动线程
    mHandler.post(mRunnable);
    }
    }

    这样在也会引发内存泄露。我们应该在onDestory方法中移除Handler,代码如下:

    @Override
    protected void onDestroy() {
    super.onDestroy();
    mHandler.removeCallbacks(mRunnable);
    }

最新文章

  1. Web APP开发技巧总结(转)
  2. Spring学习总结(三)——Spring实现AOP的多种方式
  3. Python的sorted函数应用
  4. 在sap系统设置纸张打印格式(针式打印机)
  5. ViewPager滑动页面的实现方法
  6. iOS H5 容器的一些探究(一):UIWebView 和 WKWebView 的比较和选择
  7. django下载文件
  8. 什么是DCI
  9. linux sort 用法
  10. 字符串的模式匹配(Java实现)
  11. EF增删改查+使用Expression进行动态排序分页
  12. linux 查看ip地址
  13. 将docker镜像上传到docker hub
  14. composer修改中文镜像
  15. 结对编程--C语言子程序词法分析
  16. Amazon OA
  17. [UE4]使机器人受伤
  18. 以Settings.APPLICATION_DEVELOPMENT_SETTINGS打开开发人员面板出错总结
  19. PHP中php_sapi_name()与array_map()
  20. 【转】多线程Core Data

热门文章

  1. Android Studio快捷键每日一练(5)
  2. C#--属性
  3. JAVA - HashMap和HashTable
  4. IOS 通用颜色快速生成代码
  5. 【转】 Key/Value之王Memcached初探:三、Memcached解决Session的分布式存储场景的应用
  6. ASP.NET MVC文章附加有源码下载的文章
  7. 【C#】回调方法不通过object参数获得委托实例
  8. 使用attrs.xml自定义属性
  9. MySQL建表规范与常见问题
  10. JAVA中的输入方法