Android 经典笔记之一:setOnKeyListener方法事件执行两次

2023-11-04

Android 经典总结案例一
目录介绍:
1.完美解决onActivityResult提前执行调用的一系列问题
1.1 出现的问题
1.2 解决方案
1.3 相关原理说明
1.4 知识拓展
2.EditText调用软键盘搜索的setOnKeyListener方法事件执行两次
2.1 出现的问题
2.2 解决方案
2.3 相关原理说明
2.4 知识拓展
3.关于64k方法书限制的原理和解决方案探讨
3.1 先看看报错
3.2 64k****产生原因?
3.3 如何解决64k的问题
3.4 优化Multidex的开发和构建

好消息

  • 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
  • 链接地址:https://github.com/yangchong211/YCBlogs
  • 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!

1.完美解决onActivityResult提前执行调用的一系列问题

这是原本要启动的MainActivity
int requestCode = 200;
Intent intent = new Intent(this,SecondActivity.class);
startActivityForResult(intent,requestCode);

SecondActivity回传携带的数据
Intent mIntent = new Intent();
mIntent.putExtra("addr_id", retData.get(position));
// 设置结果,并进行传送
setResult(resultCode, mIntent);     
finish()

清单文件manifest.xml配置
<activity android:name=".activity.SecondActivity" android:launchMode="singleTask"/>

**1.1.问题:**代码没有任何问题,onActivityResult方法一直回调不过来数据,debug调试以后才发现onActivityResult方法在开启另外一个activity的时候提前执行了
1.2.解决方案: 发现manifest.xml配置AddressActivity的启动模式是singleTask,就抱着试试看的态度,把他改成了标准启动模式,然后突然回传数据
1.3.原理说明:
如图:假设当前的应用程序存在两个栈:其中一个直接显示在屏幕上负责与用户完成交互,叫BackStack;另一个是隐藏在后台的background task,且位于该栈顶的Activity Y的启动模式被设置为singleTask。
参考官方文档可知:

Image.png

在上图中,存在着前两个栈,其中直接显示在屏幕上与用户交互的Back Stack,及另一个隐藏在后台的Background Task,该栈栈顶的Activity Y其launchMode为singleTask。
如果在Activity 2中调用BackgroundTask中已经启动过的Activity Y,则Background Task内占据屏幕并且该Task下所有的栈都会保留当前的栈位置及顺序push进Back Task形成新的结构,顺序由上至下为Activity Y→Activity X→Activity 2→Activity 1。
在Activity Y界面按返回键,则ActivityY出栈,Activity X占据屏幕!注意,由Activity2调用的Activity Y,但返回键后,回退显示的是Activity X!所以即使在Activity Y执行setResult(),Activity 2也是无法接收到的。换回文章开头的问题,即在JumpActivity处启动LoginActivity(已经被设置singleTask了),则LoginActivity的setResult()结果有可能不会传给JumpActivity。
继续按返回键,则才回到Activity 2。
由于这种现象的存在,所以android系统处于某种保护机制,发现将要跳转的Activity的启动模式是singleTask时,若需要执行onActivityResult()函数则立即执行。这样就好理解多了。

1.4.知识延伸:
singleTop模式,可用来解决栈顶多个重复相同的Activity的问题。
singleTask模式和后面的singleInstance模式都是只创建一个实例的。
当intent到来,需要创建singleTask模式Activity的时候,系统会检查栈里面是否已经有该Activity的实例。如果有直接将intent发送给它。
singleInstance模式解决了这个问题(绕了这么半天才说到正题)。让这个模式下的Activity单独在一个task栈中。这个栈只有一个Activity。导游应用和google地图应用发送的intent都由这个Activity接收和展示。

2.EditText调用软键盘搜索的setOnKeyListener方法事件执行两次

etProjectName.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_ENTER) {
        // 先隐藏键盘
        ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
            .hideSoftInputFromWindow(PublishProjectActivity.this.getCurrentFocus()
                .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        //进行搜索操作的方法,在该方法中可以加入mEditSearchUser的非空判断
        **search();     //执行两次,想一想为什么?**
        return true;
    }
    return false;
    }
});

**2.1.问题:**点击后事件执行两次
2.2.原理分析:
setOnKeyListener之所以执行两次就是因为down和up占用了

2.3.解决方案:
第一种方案

etProjectName.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
    **//发现执行了两次因为onkey事件包含了down和up事件,所以只需要加入其中一个即可。**
**    //这个是个取巧的办法**
**    if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN)** {
        // 先隐藏键盘
        ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
            .hideSoftInputFromWindow(PublishProjectActivity.this.getCurrentFocus()
                .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        //进行搜索操作的方法,在该方法中可以加入mEditSearchUser的非空判断
        search();     //执行两次,想一想为什么?
        return true;
    }
    return false;
    }
});

第二种方案

et.setOnEditorActionListener(new TextView.OnEditorActionListener() { 
    @Override 
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event){ 
        //判断是否是“放大镜”键【简称搜索键】
        if(actionId == EditorInfo.IME_ACTION_SEARCH){ 
        //隐藏软键盘 
        //对应逻辑操作
        return true; 
        } 
        return false; 
    } 
});

需要注意的是 setOnEditorActionListener这个方法,并不是在我们点击EditText的时候触发,也不是在我们对EditText进行编辑时触发,而是在我们编辑完之后点击软键盘上的各种键才会触发

2.4.知识延伸:
修改Editview属性:Android:imeOptions=“actionSearch” 在该Editview获得焦点的时候将“回车”键改为“搜索”

android:singleLine="true"      不然回车【搜索】会换行
可以随自己的需求更改软键盘右下角的显示样式,例如:搜索,下一步,Q(搜索图标)

actionNone : 按下后光标到下一行(回车)
actionGo : 按下后搜索(Go)
actionSearch : 放大镜【搜索】
actionSend : Send 按下后发送
actionNext : Next 下一步
actionDone : Done,确定/完成,隐藏软键盘(包括不是最后一个文本输入框的情况也会隐藏)
使用方法:在xml里面写布局时直接加给EditTxt的imeOptions属性,例如:

项目开发中涉及到按键事件处理:

**“dispatchKeyEvent” “onKeyDown ”“onKeyLisenter” 简单理解**
接受按键优先级:

**dispatchKeyEvent > Activity的onKeyDown > view的onKeyLisenter**
其中按键处理事件return true ;表示已消耗此事件,不再继续传递;

3.关于64k方法书限制的原理和解决方案探讨
3.1 先看看报错,截图如下

[图片上传中。。。(2)]
3.2 产生原因?
Android APK文件本质上是一个压缩文件,它包含的classes.dex文件是Dalvik字节码文件,这个dex文件中存放的就是编译后的Java代码。Dalvik可执行文件规范限制了单个.dex文件最多引用的方法数是65536个。Android官方的叫法是64k,也就是1024x64=65536个Java方法。
其中包含第三方库,App应用,以及Framework及自身的方法。
3.3 如何解决64k的问题
google为了规避上述问题,推出了MultiDex解决方案解决方法数超限问题。
A:首先需要配置build.gradle文件【注意是项目下的build文件】
添加代码如下所示:

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"    //必须使用21或之后的版本
    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 21       

        // Enabling multidex support.
        **multiDexEnabled true**
    }
}

dependencies {
    compile 'com.android.support:multidex:1.0.0'
}

B:配置Application
如果用户没有重写Application,只需修改Manifest文件中的内容:

<application
    android:name="android.support.multidex.MultiDexApplication">
</application>

如果用户继承变重写了Application,可以将继承的Application换成MultiDexApplication。 或者重写attachBaseContext() 方法

@Override
 protected void attachBaseContext(Context base) {
     super.attachBaseContext(base);
     MultiDex.install(this);     //这个方法是在onCreate之前执行的
}

特别注意,如果没有实现这部分代码,运行时会出现NoClassDefFoundError的错误,尤其是在依赖三方函数库时。

3.4 优化Multidex的开发和构建

这块看书后还是不太懂,

后续:
平时喜欢写写文章,笔记。别人建议我把笔记,以前写的东西整理,然后写成博客,所以我会陆续整理文章,只发自己写的东西,敬请期待:
知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
领英:https://www.linkedin.com/in/chong-yang-049216146/
简书:http://www.jianshu.com/u/b7b2c6ed9284
csdn:http://my.csdn.net/m0_37700275
网易博客:http://yangchong211.blog.163.com/
新浪博客:http://blog.sina.com.cn/786041010yc
github:https://github.com/yangchong211
喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/
脉脉:yc930211
开源中国:https://my.oschina.net/zbj1618/blog

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 经典笔记之一:setOnKeyListener方法事件执行两次 的相关文章

  • gazebo仿真与ros控制器学习

    gazebo是一个功能强大的模拟器 尤其适合机器人的运动和控制模拟 但也存在很多bug 官方学习地址 http gazebosim org tutorials 包括了所有的教程 从初级中级到高级 也可以按照分类进行学习 这里主要讲与ros控
  • 80端口被占用时的终极解决方法

    摘要 之前在某次安全测试时 遇到一个80端口被占用的坑 将解决方法共享出来 使用netstat ano 命令查看是哪个进程正在占用80端口 之前在某次安全测试时 遇到一个80端口被占用的坑 将解决方法共享出来 使netstat ano 命令
  • linux nexus 启动失败_学习笔记之——nexus(四)记一次nexus故障

    一 故障描述 nexus服务器最初配置为4C8G 随着业务量的暴增 终于在某一天不堪重负 OOM了 排查后 增加内存到16G 再次启动 然后看似正常 然后却发生了诡异的事件 二 排查过程 问题一 查看日志 发现日志报错如下 报错日志1 经确
  • imx6ull视频监控项目,从kernel,buildroot,nginx,ffmpeg实现摄像头推流,vlc及web拉流

    写这一篇目的是记录自己使用buildroot 构建根文件系统 实现摄像头推流到VLC 及 web端 主要介绍的是 1 buildroot构建根文件系统 2 ffmpeg 及nginx 的配置 3 Linux内核构建 4 如何将摄像头的视频在
  • 软件项目管理课程授课教案

    序 软件项目管理概述 第一篇 软件项目初始 第1章 软件项目初始过程 第二篇 软件项目计划 第2章 软件项目范围计划 第3章 软件项目进度计划 第4章 软件项目成本计划 第5章 软件项目质量计划 第6章 软件项目人力资源计划 第7章 软件项
  • 灵创系统服务器,服装ERP-灵创软件-ICSCM供应链管理系统

    服装ERP 灵创软件 ICSCM供应链管理系统 一 产品概述 ICSCM供应链管理系统是基于品牌营运商和产品生产商之间紧密沟通 风险利润分担的大前提下诞生的一套全B S结构的系统 它是一种致力于在企业与供应商之间建立和维持长久的紧密合作伙伴
  • STM32系列(HAL库)——F103C8T6获取DHT11温湿度串口打印

    本文参考此篇博客并在其基础上进行了修改 STM32F103驱动DHT11温湿度传感器 STM32MXcube HAL 在此特别鸣谢原文博主 1 软件准备 1 编程平台 Keil5 2 CubeMX 3 XCOM 串口调试助手 2 硬件准备
  • Manifest.json文档说明

    Manifest json文件是5 移动App的配置文件 用于指定应用的显示名称 图标 应用入口文件地址及需要使用的设备权限等信息 是扩展的配置文件 指明了扩展的各种信息 一个manifest json格式如下 必须的字段3个 name M
  • Spring bean生命周期详解

    Spring Bean的完整生命周期从创建Spring容器开始 直到最终Spring容器销毁Bean 这其中包含了一系列关键点 Spring bean生命周期 四个阶段 Bean的实例化阶段 Bean的设置属性阶段 Bean的 初始化阶段
  • token续期

    需求 项目前后端分离 采用token jwt生成 方式作为登录及接口验证 自然而然就会涉及token超时 影响用户体验的问题 要解决的就是如果用户一直点击页面 就不应该出现超时及重新登录 只有用户在设置的超时时间内 一次页面操作都没有 才定
  • 大白话给你说清楚什么是过拟合、欠拟合以及对应措施

    开始我是很难弄懂什么是过拟合 什么是欠拟合以及造成两者的各自原因以及相应的解决办法 学习了一段时间机器学习和深度学习后 分享下自己的观点 方便初学者能很好很形象地理解上面的问题 同时如果有误的地方希望大家在评论区留下你们的砖头 我会进行纠正
  • 计算机故障诊断知识,故障诊断

    利用各种检查和测试方法 发现系统和设备是否存在故障的过程是故障检测 而进一步确定故障所在大致部位的过程是故障定位 故障检测和故障定位同属网络生存性范畴 要求把故障定位到实施修理时可更换的产品层次 可更换单位 的过程称为故障隔离 故障诊断就是
  • UE4Material_材质属性(1)

    材质中的属性 物理材质 Phys Material 物理材质 与该材质关联的物理材质 物理材质 Physical Material 提供了物理属性的定义 例如碰撞 弹力 以及其他基于物理的方面会保留多少能量 物理材质 Physical Ma
  • 一篇教会你,Redis主从、哨兵、 Cluster集群。

    前言 大家好 今天跟小伙伴们一起学习Redis的主从 哨兵 Redis Cluster集群 Redis主从 Redis哨兵 Redis Cluster集群 1 Redis 主从 面试官经常会问到Redis的高可用 Redis高可用回答包括两
  • TCP的三次握手及四次挥手总结(从抓包角度理解)

    目录 TCP报文首部 TCP连接 传输及断开过程图 TCP状态图 三次握手过程理解 四次挥手过程理解 从抓包来理解TCP建立连接 数据传输以及断开连接的过程 建立连接过程 数据传输过程 连接断开过程 为什么连接的时候是三次握手 关闭的时候却
  • Keras查看model weights .h5 文件的内容

    Keras的模型是用hdf5存储的 如果想要查看模型 keras提供了get weights的函数可以查看 for layer in model layers weights layer get weights list of numpy
  • 多进程浏览器框架

    为什么浏览器采用多进程模型 转载于 http www wtoutiao com p s57age html Google Chrome源码剖析 一 多线程模型 转载于 http www ha97 com 2908 html 主流浏览器多进程
  • 【广州华锐互动】无人值守变电站AR虚拟测控平台

    无人值守变电站AR虚拟测控平台是一种基于增强现实技术的电力设备巡检系统 它可以利用增强现实技术将虚拟信息叠加在真实场景中 帮助巡检人员更加高效地完成巡检任务 这种系统的出现 不仅提高了巡检效率和准确性 还降低了巡检成本和风险 传统的变电站巡

随机推荐

  • TPM功能介绍

    文章来源 TPM功能介绍 百度文库 http wenku baidu com link url bQMQyb0A3gto0CCC2CN5ojpUrgHsh8BMXmejpFaqLS52v 013bXPHoRr36r0F0UrgPr8U6rv
  • MATLAB——FFT(快速傅里叶变换)

    基础知识 FFT即快速傅里叶变换 利用周期性和可约性 减少了DFT的运算量 常见的有按时间抽取的基2算法 DIT FFT 按频率抽取的基2算法 DIF FFT 1 利用自带函数fft进行快速傅里叶变换 若已知序列 x 4 3
  • 利用ChatGPT协助编写单元测试

    ChatGPT自从2022年推出以来受到很多人的喜欢 此篇博客重点介绍如何修改Prompt来自动生成较理想的单元测试 如下图所示的一段代码 该class中有一个public方法toLocale 其余都是private方法 toLocale
  • 编写代码的几个tip

    使用的大多是MVC的模式 那么视图就只管视图 逻辑就只管逻辑 一个自定义的cell 上面放了一个button button的点击事件用一个delegate在viewcontroller中来实现 比如先要变化cell的样式 那么代理方法中 不
  • 攻防世界WEB入门

    1 view source X老师让小宁同学查看一个网页的源代码 但小宁同学发现鼠标右键好像不管用了 WP 按F12即可在elements中看到flag 2 robots X老师上课讲了Robots协议 小宁同学却上课打了瞌睡 赶紧来教教小
  • ​LeetCode刷题实战214:最短回文串

    算法的重要性 我就不多说了吧 想去大厂 就必须要经过基础知识和业务逻辑面试 算法面试 所以 为了提高大家的算法能力 这个公众号后续每天带大家做一道算法题 题目就从LeetCode上面选 今天和大家聊的问题叫做 最短回文串 我们先来看题面 h
  • UE4 UMG中使用富文本

    UE4 UMG中使用富文本 一 新建DateTable 二 添加字体样式 注意 第一个RowName必须为Default 字体样式必须赋值 否则会乱码 我们将Default的字体改为白色 Red字体改为红色 字号改小 三 使用 拖一个富文本
  • serverTimezone设置

    在安装完mysql第一次使用IDEA进行数据库连接发现 You must configure either the server or JDBC driver via the serverTimezone configuration pro
  • uview2.0封装网络请求(微信小程序最新登录方式)

    一 网络请求和相应拦截器 此vm参数为页面的实例 可以通过它引用vuex中的变量 module exports vm gt 初始化请求配置 uni u http setConfig config gt config baseURL http
  • 计算机二级C语言三天能过吗,学工干货丨如何三天通过计算机二级

    原标题 学工干货丨如何三天通过计算机二级 不可能的 想都不要想 三天怎么可能过 不信你问考完了的 他们马上就可以 进行计算机二级考试成绩查询啦 计算机二级是什么 计算机二级怎么考 迷惘 彷徨 别怕 今天学工菌来助攻 考生在考后50个工作日
  • 博客园自定义主题代码

    发一下好看的 要开通js权限 皮肤用simple memory 最好禁用模板 侧边栏
  • 基于小脑模型神经网络的轨迹跟踪研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 1 在对人类神经学的研究中 得知它由一些神
  • class加载过程

    loading class文件 从硬盘 加载到 内存 linking 1 verification 校验 检查满不满足class文件的格式 2 preparation 将 静态变量 赋默认值 默认值是0 3 resolution 将 常量池
  • Code Embedding研究系列11-ContraFlow

    Path Sensitive Code Embedding via Contrastive Learning for Software Vulnerability Detection 一 引言 1 1 现有方法及其局限 1 2 作者的解决方
  • 24模型微调(finetune)

    一 Transfer Learning Model Finetune 1 1 Transfer Learning Transfer Learning 机器学习分支 研究源域 source domain 的知识如何应用到目标域 targetd
  • <图像处理> Canny边缘检测

    Canny边缘检测 边缘检测评判标准 低错误率 在图像中精确地检测出尽可能多的边缘 并尽量减少漏检和误检 高定位精度 检测出的边缘点应该精确地定位于边缘的中心 边缘唯一性 图像中的每条边缘只被标记一次 同时避免由于噪声干扰产生虚假边缘 Ca
  • doesn‘t belong to any package and ProcessUnpackaged is set to ‘no‘

    数据库日志 开发反馈数据库连接异常 查看数据库日志发现像是服务器把数据库进程kill掉了 2021 04 09 18 48 23 578 CST 78992 606fca0d 13490 80 2021 04 09 11 29 17 CST
  • TypeScript详解

    目录 一 梦开始的地方 1 什么是TypeScript 2 TS开发环境搭建 3 Hello world 二 变量类型 1 原始类型 2 数组类型 3 联合类型 4 自定义类型 类型别名 5 函数类型 6 对象类型 7 接口 8 元组 9
  • smbclient递归目录下载文件

    连接到某个smb服务的share后 依次执行以下命令 recurse ON 开启递归 开启后会以目录递归方式运行mget和mput命令 prompt OFF 关闭交互 开启后 下载文件时不再要求输入y n确认 megt 批量获取文件 是一个
  • Android 经典笔记之一:setOnKeyListener方法事件执行两次

    Android 经典总结案例一 目录介绍 1 完美解决onActivityResult提前执行调用的一系列问题 1 1 出现的问题 1 2 解决方案 1 3 相关原理说明 1 4 知识拓展 2 EditText调用软键盘搜索的setOnKe