Android笔记----第三天
1、获取Context对象,主要有以下四种方法
1.View.getContext,返回当前View对象的Context对象,通常是当前正在展示的Activity对象。
2.Activity.getApplicationContext,获取当前Activity所在的(应用)进程的Context对象,通常我们使用Context对象时,要优先考虑这个全局的进程Context。
3.ContextWrapper.getBaseContext():用来获取一个ContextWrapper进行装饰之前的Context,可以使用这个方法,这个方法在实际开发中使用并不多,也不建议使用。
4.Activity.this 返回当前的Activity实例,如果是UI控件需要使用Activity作为Context对象,但是默认的Toast实际上使用ApplicationContext也可以。
当Application的Context能搞定的情况下,并且生命周期长的对象,优先使用Application的Context。
不要让生命周期长于Activity的对象持有到Activity的引用。
尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。
2、如何进行布局优化?
1.删除布局中无用的控件和层次,其次有选择地使用性能比较低的ViewGroup。
例如:
如果布局中既可以使用LinearLayout也可以使用RelativeLayout,那么就采用LinearLayout,这是因为RelativeLayout的功能比较复杂,它的布局过程需要花费更多的CPU时间。
FrameLayout和LinearLayout一样都是一种简单高效的ViewGroup,因此可以考虑使用它们,但是很多时候单纯通过一个LinearLayout或者FrameLayout无法实现产品效果,需要通过嵌套的方式来完成。
这种情况下还是建议采用RelativeLayout,因为ViewGroup的嵌套就相当于增加了布局的层级,同样会降低程序的性能。
2.采用标签,标签,ViewStub。
标签主要用于布局重用。
标签一般和配合使用,可以降低减少布局的层级。
ViewStub提供了按需加载的功能,当需要时才会将ViewStub中的布局加载到内存,提高了程序初始化效率。
3.避免多度绘制
过度绘制(Overdraw)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次重叠的 UI 结构里面,如果不可见的 UI 也在做绘制的操作,会导致某些像素区域被绘制了多次,同时也会浪费大量的 CPU 以及 GPU 资源。
3、线程优化
线程优化的思想就是采用线程池,避免程序中存在大量的Thread。
线程池可以重用内部的线程,从而避免了线程的创建和销毁锁带来的性能开销,同时线程池还能有效地控制线程池的最大并法术,避免大量的线程因互相抢占系统资源从而导致阻塞现象的发生。
因此在实际开发中,尽量采用线程池,而不是每次都要创建一个Thread对象。
4、其他性能优化建议
1.避免过度的创建对象
2.不要过度使用枚举,枚举占用的内存空间要比整型大
3.常量请使用static final来修饰
4.用一些Android特有的数据结构,比如SparseArray和Pair等
5.适当采用软引用和弱引用
6.采用内存缓存和磁盘缓存
7.尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄漏。
5、Java 内存分配策略
Java 程序运行时的内存分配策略有三种,分别是静态分配,栈式分配,和堆式分配,对应的,三种存储策略使用的内存空间主要分别是静态存储区(也称方法区)、栈区和堆区。
1.静态存储区(方法区):主要存放静态数据、全局 static 数据和常量。这块内存在程序编译时就已经分配好,并且在程序整个运行期间都存在。
2.栈区 :当方法被执行时,方法体内的局部变量都在栈上创建,并在方法执行结束时这些局部变量所持有的内存将会自动被释放。因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
3.堆区 : 又称动态内存分配,通常就是指在程序运行时直接 new 出来的内存。这部分内存在不使用时将会由 Java 垃圾回收器来负责回收。
局部变量的基本数据类型和引用存储于栈中,引用的对象实体存储于堆中。—— 因为它们属于方法中的变量,生命周期随方法而结束。
成员变量全部存储于堆中(包括基本数据类型,引用和引用的对象实体)—— 因为它们属于类,类对象终究是要被new出来使用的。
6、内存泄漏
1.对 Activity 等组件的引用应该控制在 Activity 的生命周期之内; 如果不能就考虑使用 getApplicationContext 或者 getApplication,以避免 Activity 被外部长生命周期的对象引用而泄露。
2.尽量不要在静态变量或者静态内部类中使用非静态外部成员变量(包括context ),即使要使用,也要考虑适时把外部成员变量置空;也可以在内部类中使用弱引用来引用外部类的变量。
3.对于生命周期比Activity长的内部类对象,并且内部类中使用了外部类的成员变量,可以这样做避免内存泄漏:
4.将内部类改为静态内部类
5.静态内部类中使用弱引用来引用外部类的成员变量
6.Handler 的持有的引用对象最好使用弱引用,资源释放时也可以清空 Handler 里面的消息。比如在 Activity onStop 或者 onDestroy 的时候,取消掉该 Handler 对象的 Message和 Runnable.
7.在 Java 的实现过程中,也要考虑其对象释放,最好的方法是在不使用某对象时,显式地将此对象赋值为 null,比如使用完Bitmap 后先调用 recycle(),再赋为null,清空对图片等资源有直接引用或者间接引用的数组(使用 array.clear() ; array = null)等,最好遵循谁创建谁释放的原则。
8.正确关闭资源,对于使用了BraodcastReceiver,ContentObserver,File,游标 Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销。
9.保持对对象生命周期的敏感,特别注意单例、静态对象、全局性集合等的生命周期。
7、SQL语句
1.创建表
CREATE TABLE tableName ( tdName dataType tdConstraint… );
–tdConstraint可选NULL / NOT NULL / UNIQUE
2.删除表
DROP TABLE tableName;
3.清空表
TRUNCATE TABLE tableName;
4.修改表
– 添加列
ALTER TABLE tableName ADD tdNewName dataType tdConstraint;
– 删除列
ALTER TABLE tableName DROP COLUMN tdName;
– 修改列
ALTER TABLE tableName MODIFY COLUMN tdName dataType tdConstraint;
5.查询表
SELECT * FROM tableName
WHERE tdNameMathCount
GROUP BY tdName HAVING tdNameMathCount
ORDER BY tdName DESC
–HAVING子句只能与GROUP BY搭配使用
– 插入不存在的数据
INSERT INTO tableName(tdName1,tdName2) VALUES (‘data1’,data2);
– 将查询的数据插入到数据表中
INSERT INTO tableName(tdName1,tdName2)
SELECT tdName1,tdName2 FROM tableName2 WHERE tdNameMathCount;
6.更新表
UPDATE tableName SET tdName=tdNameMathCount WHERE tdNameMathCount1 AND tdNameMathCount2
7.删除
DELETE FROM tableName WHERE tdNameMathCount;