采用匿名内部类形式定义Handler有什么不妥?

news2024/12/23 22:26:38

写这篇博客,是为分析Handler引起内存泄漏做准备。

目录

      • 匿名内部类的含义是什么?
      • 匿名内部类的三种情况
      • 非静态内部类为什么会持有外部类的引用?

匿名内部类的含义是什么?

首先是内部类,(内部类不难理解,有时间再分析,这里不展开)为什么称之为匿名?因为没有明确定义类的名称。看下面的例子就知道了。

匿名内部类的三种情况

  • 实现接口的匿名内部类
    例如android中常用的setOnClickListener()runOnUiThread()
public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
	...
    public interface OnClickListener {
        void onClick(View v);
    }
	...
} 

		//使用:
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

View.OnClickListener只是接口名称,真正的类名,并没有给出。完整的写法,应该是:

    class TVListener implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            System.out.println("onClick");
        }
    }
	
    tv.setOnClickListener(new TVListener());

TVListener就是具体的类名。

  • 继承抽象类的匿名内部类。实现抽象方法,不举例了。
  • 继承普通类的匿名内部类。重写普通的某个方法,Android中的典型例子就是Handler,一般都会重写handleMessage()方法。
public class StandardActivity extends AppCompatActivity {
    private static final String TAG = "ActivityA";
    private Handler myHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 100) {
                Log.i(TAG, "xxx");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate: ");
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message msg = new Message();
                msg.what = 100;
                myHandler.sendMessage(msg);
            }
        }).start();
    }
}

非静态内部类为什么会持有外部类的引用?

静态内部类是不会持有外部类的引用的。详细查看:为啥非静态内部类能持有外部类?
我们写三个类,看看编译出来的.class文件。

//模拟Android SDK中Activity.java
public class Activity {

}

//模拟Android SDK中的Handler.java
public class Handler {
    public void handleMessage(){

    }
}

//模拟实际开发中的MainActivity
public class MainActivity extends Activity {

    Handler mH;

    public void onCreate() {
        mH = new Handler() {
            @Override
            public void handleMessage() {
                System.out.println("重写handleMessage()方法");
            }
        };

        System.out.println(mH.getClass().getName());
    }

    public static void main(String[] args) {
        new MainActivity().onCreate();
    }
}

编译完,确实生成了4个.class文件:

看看MainActivity$1.class,构造器里面确实传入了MainActivity的对象var1。

class MainActivity$1 extends Handler {
    MainActivity$1(MainActivity var1) {
        this.this$0 = var1;
    }

    public void handleMessage() {
        System.out.println("閲嶅啓handleMessage()鏂规硶");
    }
}

有点不确定,如果不是匿名内部类,仅仅是非静态内部类,会不会也持有引用了?
试下:

public class OutClass {
    class InClass{

    }
}

编译后:

看看OutClass$InnerClass.class文件:

class OutClass$InClass {
    OutClass$InClass(OutClass var1) {
        this.this$0 = var1;
    }
}

还是在构造器中传入了外部类OutClass的引用。注意:这说明,即使不采用匿名内部类,采用非静态成员内部类的形式,定义Handler,也还是会持有Activity的引用。所以只能使用静态内部类的方式自定义Handler。

所以非静态内部类的.class文件中,构造器会自动传入外部类的引用。不管是不是匿名,只要是非静态内部类,默认持有外部类的引用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/717995.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPS Office AI实战:一键生成PPT幻灯片

前些天WPS Office AI放出来内测申请,相信不少小伙伴都拿到了体验资格,不知道体验到国产AI的魅力没有?作为写作中的重头戏,一张PPT的制作让不少小伙伴面露难色,单排版布局这一项就足以让人望而却步。 AI 在写作中的应用…

使用EXCEL公式编程从网页获取股票数据并保存到excel

共享文件地址 在dataexcel服务器的 /示例/03函数示例/获取股票数据8.fexm 路径 公式脚本 var urlcelltext("URL");//获取单元格ID为URL的单元格内容 var txtWebGet(url); //从网页获取数据 cellvalue("data",txt); //将获取到的数据库保存到ID为DATA的单…

SSM学习笔记-------MyBatis

MyBatis学习笔记 一、入门二、XML配置1、configuration(配置)2、properties(属性)3、settings(设置)4、typeAliases(类型别名)5、typeHandlers(类型处理器)6、…

Elasticsearch Dump的详细安装和迁移es索引和数据的使用教程

前言 如果希望将数据导出到本地文件而不是通过编程方式处理,可以考虑使用Elasticsearch的导出工具,如Elasticsearch Dump(Elasticdump)或Elasticsearch Exporter。这些工具可以将Elasticsearch索引中的数据导出为可用于后续处理的…

备战秋招002(20230704)

文章目录 前言一、今天学习了什么?二、关于问题的答案1.线程池2.synchronized关键字3、volatile 总结 前言 提示:这里为每天自己的学习内容心情总结; Learn By Doing,Now or Never,Writing is organized thinking. …

vue3+wangEditor5/vue-quill自定义上传音频+视频

一.各种编辑器分析 Quill 这是另一个常用的富文本编辑器,它提供了许多可定制的功能和事件,并且也有一2个官方的 Vue 3 组件 wangEditor5 wangEditor5用在Vue3中自定义扩展音频、视频、图片菜单;并扩展音频元素节点,保证音频节…

【数据结构与算法篇】之时间复杂度与空间复杂度

【数据结构与算法篇】之时间复杂度与空间复杂度 一、时间复杂度1.1时间复杂度的定义1.2 常见的时间复杂度的计算1.2.1 常数时间复杂度( O ( 1 ) ) O(1)) O(1))1.2.2 线性时间复杂度( O ( N ) O(N) O(N))1.2.3 对数时间复杂度( O (…

蓝桥杯专题-试题版含答案-【荷兰国旗问题】【正三角形的外接圆面积】【比较字母大小】【车牌号】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

SSTI模板注入

目录 1、原理简述 2、常用payload及相关脚本 (1).__class__ (2).__class__.__base__ (3).__class__.__base__.__subclasses__() (4).__class__.__base__.__subclass…

【周末闲谈】浅谈“AI+算力”

随着人工智能技术的飞速发展,“AI算力”的结合应用已成为科技行业的热点话题,甚至诞生出“AI算力最强龙头“的网络热门等式。该组合不仅可以提高计算效率,还可以为各行各业带来更强大的数据处理和分析能力,从而推动创新和增长。 文…

ue4:Dota总结—HUD篇

1.绘制ui: DrawMoney: DrawPower: 点击ui响应事件: 点击响应显示对应的模型: 点击ui拖动模型跟随鼠标移动: 显示ui:PlayerContrler:

【JAVA】Java 开发环境配置(WIndows篇)

个人主页:【😊个人主页】 系列专栏:【初始JAVA】 文章目录 前言下载JDK配置环境变量JAVA_HOME 设置PATH设置CLASSPATH 设置变量设置参数 前言 在前篇中我们介绍了JAVA语言的诞生与发展,现在是时候去学习使用他们了。 下载JDK 首先…

常微分方程(ODE)求解方法总结(续)

常微分方程(ODE)求解方法总结(续) 1 隐式方法2 多步法2.1 二阶方法2.1.1 非自启动修恩方法2.2 开型和闭型积分公式2.3 高阶多步法 1 隐式方法 常微分方程(ODE)求解方法总结 里面介绍了我称为“正常思路”的…

Jira UI Locations及注意事项总结

issue view ui locations : https://developer.atlassian.com/server/jira/platform/issue-view-ui-locations/#issue-operations-bar-locations1.问题操作栏Issue Operations Bar Locations模块分为两部分: opsbar-operationsflopsbar-transitions两个location.共同定义了问题…

【力扣】111、二叉树的最小深度

111、二叉树的最小深度 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明:叶子节点是指没有子节点的节点。 // var minDepth function(root){if(!root) return 0;const stack [ [ root ,1] ];//…

零拷贝详解

目录 一、什么是零拷贝 二、传统的IO执行流程 三、零拷贝相关的知识点回顾 1、内核空间&用户空间 2、用户态&内核态 3、上下文切换 4、虚拟内存 5、DMA技术 四、零拷贝实现的几种方式 1、mmapwrite实现的零拷贝 2、sendfile实现的零拷贝 3、sendfileDMA sc…

MySQL原理探索——23 MySQL是怎么保证数据不丢的

今天这篇文章,我会继续介绍在业务高峰期临时提升性能的方法。从文章标题“MySQL 是怎么保证数据不丢的”,你就可以看出来,今天我介绍的方法,跟数据的可靠性有关。 在前面文章,我都着重介绍了 WAL 机制(你可…

ElementUI plus框架Table表格cell-style属性的使用

官方文档说明: 例:设置单元格文字居中 Object方式: function方式:

安全 --- http报文包详解及burp简单使用

HTTP HTTP(超文本传输协议)是今天所有web应用程序使用的通信协议。最初HTTP只是一个为了获取基本文本的静态资源而开发的简单协议,后来对其进行扩展和利用,使其发展为能够支持如今常见的复杂分布式应用程序。 (1&…