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

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/m0_37700275/article/details/76944153

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

阅读更多
换一批

没有更多推荐了,返回首页