Android 经典笔记之一

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容