0. 前言

本文转载自AItsuki的博客。

首先说明一下为什么要写这么一篇博客:最近看了一些其他人的项目,发现很多项目的做法是建立一个专门存放Adapter类的Package包,也有的项目干脆直接都写在Activity中。而我属于后者,我并不觉得Adapter需要单独占用一个包,因为大多数时候他们并不能给其他Activity复用。

其实这两种方式都是可以的,但有一点很关键,那就是无论如何,adapter不能持有activity的引用,否则可能会因为adapter里面可能会做一些耗时操作,当activity finish时会因为被adapter持有引用而导致activity无法被回收,从而导致内存泄漏。

1. 写在Activity外面也可能会导致内存泄漏

Java中,非静态内部类对象是会隐式持有外部类引用的,也就是说adapter持有了activity的引用。所以就有将Adapter写在单独的一个包中的做法,估计很多开发者都认为这样是为了让Activity看起来更简洁。

然而我还想说的是,adapter写在外面也阻止不了MDZZ程序员想在adapter内持有Activity引用。因为很多时候adapter不可避免的需要和Activity交互,或者需要一个context对象

比如说点击列表上的Item实现到跳转SecondActivity的效果,很多人可能这么做:

//外面的Adapter类
public class ExampleAdapter extends BaseAdapter {
private Context mContext;
public ExampleAdapter(Context context) {
this.mContext = context;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
//这里也用到了activity的引用
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, null);
}
TextView textView = (TextView) convertView.findViewById(R.id.text);
textView.setText(String.valueOf(position)); Button button = (Button) convertView.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//使用构造方法传过来的上下文跳转界面
mContext.startActivity(new Intent(mContext, SecondActivity.class));
}
}); return convertView;
}
//MainActivity代码展示
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView);
//这里将activity对象传入adapter
ExampleAdapter adapter = new ExampleAdapter(this);
listView.setAdapter(adapter);
}
}

说实话,我第一次看上面代码,感觉很干净利落,甚至觉得有点舒服,=。=

但是这种情况下,adapter就持有了Activity引用,如果我们在adapter中进行耗时操作(比如加载图片之类的),并且finish Activity,虽然此时Activity销毁了,但是GC是无法回收activity的,而且Activity占用的内存还是比较大的,这样就发生了内存泄漏。

2. 不持有Activity对象的情况下怎么和Activity交互

那么在上面的例子中,问题就集中在了如何在不持有Activity对象的情况下和Activity交互。

2.1 首先处理getView()中的inflate()

当我们inflate一个xml时,完全可以使用parent的context,实现如下:

2.2 点击事件,可以用回调接口

使用回调接口的方式来实现不持有activity的情况下,与Activity愉快的交互,实现如下:


3. 其实写在里面也可以呀

adapter写在Activity里面的话只需要加个static关键字(变为静态内部类)就行了,其他和写在外面是一样的。

至此关于关于ListView的Adapter应该写在Activity外面还是里面的问题就讨论结束了,其实两种方式都可以,只要留意内存泄漏的风险即可。

Android开发——告诉你Adapter应该写在Activity里面还是外面的更多相关文章

  1. 【转】Android开发笔记(序)写在前面的目录

    原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经 ...

  2. Android开发之手把手教你写ButterKnife框架(三)

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52672188 本文出自:[余志强的博客] 一.概述 上一篇博客讲了, ...

  3. Android开发之手把手教你写ButterKnife框架(二)

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52664112 本文出自:[余志强的博客] 上一篇博客Android开 ...

  4. [Android开发学iOS系列] iOS写UI的几种方式

    [Android开发学iOS系列] iOS写UI的几种方式 作为一个现代化的平台, iOS的发展也经历了好几个时代. 本文讲讲iOS写UI的几种主要方式和各自的特点. iOS写UI的方式 在iOS中写 ...

  5. Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式

    Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...

  6. 优秀Android开发简历都是这么写,你学会也可以进大厂

    最近收了很多程序员的简历,工作经验从1年到十几年不等.发现一个问题,工作经验范围差不多的程序员,简历看起来也差不多... 为啥程序员的简历如此统一?正好最近看到一个分享也分析了这个问题,结合我个人的一 ...

  7. Android开发笔记(8)——调用子Activity

     转载请注明:http://www.cnblogs.com/igoslly/p/6853730.html  调用子Activity 需要子Activity返回值 MainActivity使用start ...

  8. Android开发学习之Adapter

    Adapter是指适配器的意思,在Android中,适配器扮演者重要的角色,是UI与Data实现绑定的一个桥梁.Adapter负责创建和显示每个项目的子View和提供对下层数据的访问.支持Adapte ...

  9. Android开发之手把手教你写ButterKnife框架(一)

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52662376 本文出自:[余志强的博客] 一.概述 JakeWhar ...

随机推荐

  1. 从产品展示页面谈谈Hybris的特有概念和设计结构

    今天这篇文章来自我的同事,SAP成都研究院Hybris开发团队的开发人员Zhang Jonathan(张健).需要特别介绍的是,张健和成都研究院的其他开发同事不同,张健毕业于电子科技大学,读的专业是英 ...

  2. python入门10 循环语句

    两种循环: 1 for in 2 while #coding:utf-8 #/usr/bin/python """ 2018-11-03 dinghanhua 循环语句 ...

  3. 什么是Load Average?

    运维工程师在日常运维中经常使用w.top.uptime等命令来查看系统当前运行的负载情况.那么作为运维工程师是如何通过以上命令来判断系统当前负载是否已经达到极限了呢?为此笔者总结了一下如何通过load ...

  4. NEUACM1132: Renew MST Quickly 增量最小生成树

    题目链接:http://acm.neu.edu.cn/hustoj/problem.php?id=1132 和UVa11354很类似 题意: 原先有一棵树,每次加一条边,看最小生成树大小: 这个和增量 ...

  5. 【转】ConcurrentHashMap原理分析(1.7与1.8)

    https://www.cnblogs.com/study-everyday/p/6430462.html 前言 以前写过介绍HashMap的文章,文中提到过HashMap在put的时候,插入的元素超 ...

  6. 【转】scp命令详解

    先说下常用的情况: 两台机器IP分别为:A.104.238.161.75,B.43.224.34.73. 在A服务器上操作,将B服务器上/home/lk/目录下所有的文件全部复制到本地的/root目录 ...

  7. Java字符串常量池是什么?为什么要有这种常量池?

    简单介绍 Java中的字符串常量池(String Pool)是存储在Java堆内存中的字符串池.我们知道String是java中比较特殊的类,我们可以使用new运算符创建String对象,也可以用双引 ...

  8. 【题解】洛谷P1445 [Violet]樱花 (推导+约数和)

    洛谷P1445:https://www.luogu.org/problemnew/show/P1445 推导过程 1/x+1/y=1/n! 设y=n!+k(k∈N∗) 1/x​+1/(n!+k)​=1 ...

  9. 菜鸟崛起 DB Chapter 1 数据库概述

    1. 数据库的概述 在目前阶段,如果要存储和管理数据,则离不开数据库.当数据存储到数据库后,就会通过数据库管理系统对这些数据进行组织和管理.数据库由一批数据构成有序的集合,这些数据被存放在结构化的数据 ...

  10. ROUND()和TRUNC()函数

    ROUND(number[,decimals]) 其中:number 待做截取处理的数值: decimals 指明需保留小数点后面的位数,可选项.需要注意的是,和trunc函数不同,对截取的数字要四舍 ...