RedDargon
                                            RedDargon
                                        
                                    launchMode即Activity的启动模式 。可以在manifest里面设定 ,一共四种类型: 1.standard 默认状态 ,不管存不存在 只要start 就会创建。 2.singleTop 不存在此界面就会创建,而界面如果处于栈顶 再次start,只会执行onNewIntent 而不是重新开启个新的界面 。 3.singleTask 不存在此界面就会创建,而界面如果在栈中 再次start 会把处于他上面的界面全部扔掉并把他抬到栈顶 并执行onNewIntent。 4.singleInstance start后会为此Activity单独开启一个栈,再次开启会判断此Activity是否存在 存在就会跳到此栈 显示此界面。设置了此启动模式的Activity 必定单例。 大多数界面都会设置singleTop ,主页会设置singleTask 。singleInstance的界面 多为系统界面吧 比如打电话界面。
OOM 即 out of memory 内存溢出 。 每个进程能够支配的内存是有限的,所以资源要记得使用完及时释放,如果未释放,就有可能造成内存泄漏,内存泄漏达到一定程度 手机就会造成内存溢出。 业务场景上面的话多为加载过大的图片,或者代码问题造成的各种内存泄漏累积出现的内存溢出 。
1.Context是个抽象类 Activity跟Application跟Service都间接继承于他 2.Context简称上下文 。Android不像java程序一样,随便创建一个类写个main方法就能跑了,它需要有一个完整的上下文环境,即context,像启动activity/broadcast receiver /service 都需要用到他。 3.context导致的内存泄漏多是长生命周期去持有了短生命周期的实例造成的。像工具类如果需要context的话,能传applicationCOntext 最好传它。 4.getApplication()跟getApplicationContext() 本质没有区别 后者就是把返回的application强转成context传回来而已。返回的都是同一个对象,只是前者只能在Activity跟Service中可以使用,作用域不同。 5.Context数量 = Activity数量 + Service数量 + 1 如果多个进程的话 后面就不是+1 而是加多个 6.ContextWrapper里面有一个attachBaseContext()方法,目的是将Context参数传给mBase,之后的调用系统方法如getPackageName()之类的都是委托mBase实例来做的,所以在调用这个方法之前 是无法调用系统方法的。 构造函数-->attachBaseContext()-->onCreate() 。所以在onCreate()中或者重写这个方法后调用都可以。 @Override protected void attachBaseContext(Context...
1.抽象类跟接口都是为了抽取共性而存在的。 2.抽象类可以有实现方法 ,接口不可以(Java8可以 但是要求api过高 没啥用) 3.java是单继承多实现 所以一个类只能继承一个抽象类,但是可以实现多个实现类。 4.从理解上来讲抽象类 ,更多的是定性为一种类型 ,而接口则定义为一种功能 一种行为。 5.抽象类可以有构造方法跟静态方法/代码块 ,而接口不可以。
需要被释放的资源没有被及时释放 就会造成内存泄漏 。 可能的场景有好些种 ,大多都是因为异步操作造成的 ,或者生命周期长的持有了生命周期短的引用。 1.handler 消息 2.非静态内部类 3.异步操作 还有AsyncTask 等 4.静态类持有非静态类 比如工具类莫名持有context 5.资源对象未关闭(File流 Cursor ) 6.注册监听 未及时注销
1.SharePreferences是线程安全的 里面的方法有大量的synchronized来保障。 2.SharePreferences不是进程安全的 即使你用了MODE_MULTI_PROCESS 。 3.第一次getSharePreference会读取磁盘文件,异步读取,写入到内存中,后续的getSharePreference都是从内存中拿了。 4.第一次读取完毕之前 所有的get/set请求都会被卡住 等待读取完毕后再执行,所以第一次读取会有ANR风险。 5.所有的get都是从内存中读取。 6.提交都是 写入到内存和磁盘中 。apply跟commit的区别在于 apply 是内存同步 然后磁盘异步写入任务放到一个单线程队列中 等待调用。方法无返回 即void commit 内存同步 只不过要等待磁盘写入结束才返回 直接返回写入成功状态 true or false 7.从 Android N 开始, 不再支持...
同属于动画 但是补间动画并没有真正的改变了view的状态,而属性动画作用在了属性上面,任何存在都可以用属性动画。 补间动画只有四种类型 平移 缩放 透明度 旋转 属性动画 只要有这个属性 提供了set方法 就可以作用得到 。
在主线程进行耗时操作,导致用户的操作没得到及时的响应 就会报出 Application Not Response 的问题 即ANR 。 这种情况往往涉及到四大组件,四大组件都是运行在主线程上的。各个组件的耗时时长不同。大概是在activity是五秒 ,广播是十秒 ,service是20秒 无响应 就会报错。 解决方法 即不要在主线程做耗时操作咯,异步处理耗时操作。
Handler +Message+MessageQueue+Looper handler做线程间通信用的。 Message 用来做消息本体 MessageQueue 用来做 消息队列 无限循环 Looper 轮询MessageQueue 看到有消息了 就会拿出来处理。 当有消息需要传递时 可以通过用handler来post/send一个message到MessageQueue里面去,然后looper发现队列里面有消息了 ,拿出来处理,调用这个消息绑定的target,最终调用到handler的handlerMessage()方法。 另外创建handler必须要有个Looper,主线程不需要这么做是因为系统以及自动创建Looper,也自动调用了Looper.loop()开启了循环。 子线程的话 就需要手动 Looper.prepare()来创建looper跟Looper.loop()开启循环。 还有上面说的 开启的死循环 当没有消息时会通过native方法来阻塞的,所以不用害怕会卡死。 至于主线程的消息队列 为什么不会ANR呢? 当没有消息时候,系统会通过linux的管道机制 让主线程进入休眠状态 。而ANR是因为消息没人处理。
默认的handler 在处理信息时可以延迟处理, 那么就会导致activity关闭时 有可能消息还未处理完毕 ,此时未被处理的消息会持有handler, handler又会持有activity, 从而导致内存泄漏。 解决办法就是 静态内部类化handler ,弱引用activity,并且在activity退出时 ,将handler绑定的Message还未执行完毕的消息 全部remove掉。