android总结一些知识点

熟练掌握Android四大组件
1.activity
是我们android程序的界面,就像windows的窗口一样,实际上activity也是继承了view类。activity的是”活动“,也就是说这是我们的android程序的
主要的应用框架。我们每一个程序的可视的界面都是一个activity,通常呢我们有back stack,在你使用完一个activty
之后,就会到了stack中,是先进后出的原则。当完成当前的activty之后,按back 就会出现栈中的下一个元素。

其他的stack模式也就是说activty的启动模式有:
strand 每次都创建activity并启动
singletop 栈顶有activity就会重用,没有就不重用
singleinstance 只有一个实例,例如金山词典,他使用自己的任务栈,不会用其他的。
singletask (浏览器)当使用的时候,会遍历所有的任务站,然后去找到实例,加载activity,当你使用singletask的
时候,假如存在,会调用onnewintent(),不会调用oncreate,而是会执行onrestart。。。

生命周期:
也就是每到特定的时间或事件触发的:

当你结束一个activity的时候,你要使用finish,但是不要显示的自己调用,会改变用户体验。不提倡,但是你要不希望
用户看到,令当别论。

2.service
是服务,我们可以看到的是长期运行在后台的一种服务,我们使用service可以无限期的运行在你的后台。
intentservice是继承与service,他会有一个onhandleintent来处理传递的intent(根据你返回的值,他会有不同的处理
。就像一个任务栈一样,
是里一个任务线程中去执行的。直到执行完所有的任务。

ipc的aidl绑定:

使用绑定的方式,绑定服务,就可以使用绑定的方法了。
当绑定之后,如果你销毁了activity,那么你的服务也就销毁了。

信使:
final Messenger mMessenger = new Messenger(new IncomingHandler());
return mMessenger.getBinder();
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
}
}
}
这样就可以使用messeenger来处理

要注意,你的服务如果是多线程的,建议用aidl

broadcast reciver
-------------------------------
熟悉进程间通信IPC,Intent数据传递,Handler消息机制和异步加载

 

Message :消息。其中包含了消息的id,消息处理的对象,还有处理消息的数据,由MessageQueue统一管理,终由Handler处理
Handler:消息处理器,负责Message的发送和处理,使用Handler时,需要实现handlerMessage()方法来对特定的Message处理
MessageQueue: 消息队列,用来存放Handler发送过来的消息,并按照fifo规则执行,当然Message并非实际意义的存储,而是蒋
Message以链表的方法串联起来,等待looper的抽取
Looper 消息泵:不断地从MessageQueue中抽取Message执行,因此,一个MessageQueue需要一个Looper.
HandlerThread 线程:负责调度整个消息循环,也就是消息循环的执行场所。


-------------------------------
熟悉Android启动流程,熟练使用异步查询框架

 

在一般的应用中可以使用ContentProvider去操作数据库。
这在数据量很小的时候是没有问题的,但是如果数据量大了,可能导致UI线程发生ANR异常(超过5秒)。
当然你也可以写个Handler去做这些操作,只是你每次使用ContentProvider时都要再写个Handler,必然降低了效率。
因此当数据量较大时,最好还是使用Android已经封装好的异步查询框架AsyncQueryHandler,优化我们的代码.

要注意的是,一般在查询本地的应用的数据的时候要去采用CursorAdapter。

过滤框架:使用autoccomplatetextview


android启动流程:
init进程是启动的第一个进程,是一个引导进程,也是一个用户进程

创建文件目录,挂载sdcard。。 ril-d和通话有关的进程 modem 动画有关的 bootsound
启动servicemanager zygote 只有创建了这两个进程,才会创建android空间。
servicemanager 管理底层的服务
在你的system_server\library\system_init
zygote 孵化器: 1.创建了android运行环境 2.创建了dalvik vm 3.创建所有的上层的进程
给进程分配了内存空间,
在systemserver这个类里面:
android第一个先启动的应用:
输入法,启动的时候开了一个输入法的服务,
电话, android里面有一中应用,持久应用(杀不死的进程phone)条件:1.配置persistent = true
2.该应用程序的apk必须放置于syste/app目录下

activititymanagerservice会去加载这些应用,然后activitymanager会去开启lanuch

 

 

--------------------------------
熟悉自定义控件和view的绘制流程|熟练 | 24

 


DecorView extends FrameLayout是所有view的根视图,是phonewindow的一个内部类
当你配置好一个activity的时候,我们会去setcontentview开始绘制流程:也就是加载decorview,以及创建一个view树


1.measure:测量:
为整个View树计算实际的大小,即设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性:
mMeasureWidth),每个View的控件的实际宽高都是由父视图和本身视图决定的。

具体的调用链如下:
ViewRoot根对象地属性mView(其类型一般为ViewGroup类型)调用measure()方法去计算View树的大小,回调
View/ViewGroup对象的onMeasure()方法,该方法实现的功能如下:
1、设置本View视图的最终大小,该功能的实现通过调用setMeasuredDimension()方法去设置实际的高(对应属性:
mMeasuredHeight)和宽(对应属性:mMeasureWidth) ;
2 、如果该View对象是个ViewGroup类型,需要重写该onMeasure()方法,对其子视图进行遍历的measure()过程。

public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
onMeasure(widthMeasureSpec, heightMeasureSpec);
}

也可以看出他是不可以被覆写的,但是会回调onmesure
setMeasuredDimension(h , l) ; 这个方法是设置实际的高和宽


2.layout 布局
主要作用 :为将整个根据子视图的大小以及布局参数将View树放到合适的位置上。

具体的调用链如下:
host.layout()开始View树的布局,继而回调给View/ViewGroup类中的layout()方法。具体流程如下

1 、layout方法会设置该View视图位于父视图的坐标轴,即mLeft,mTop,mLeft,mBottom(调用setFrame()函数去实现)
接下来回调onLayout()方法(如果该View是ViewGroup对象,需要实现该方法,对每个子视图进行布局) ;

2、如果该View是个ViewGroup类型,需要遍历每个子视图chiildView,调用该子视图的layout()方法去设置它的坐标值。


3.draw 绘制

由ViewRoot对象的performTraversals()方法调用draw()方法发起绘制该View树,值得注意的是每次发起绘图时,并不
会重新绘制每个View树的视图,而只会重新绘制那些“需要重绘”的视图,View类内部变量包含了一个标志位DRAWN,当该
视图需要重绘时,就会为该View添加该标志位。

1 、绘制该View的背景
2 、为显示渐变框做一些准备操作(见5,大多数情况下,不需要改渐变框)
3、调用onDraw()方法绘制视图本身 (每个View都需要重载该方法,ViewGroup不需要实现该方法)
4、调用dispatchDraw ()方法绘制子视图(如果该View类型不为ViewGroup,即不包含子视图,不需要重载该方法)
值得说明的是,ViewGroup类已经为我们重写了dispatchDraw ()的功能实现,应用程序一般不需要重写该方法,但可以重载父类
函数实现具体的功能。

4.1 dispatchDraw()方法内部会遍历每个子视图,调用drawChild()去重新回调每个子视图的draw()方法(注意,这个
地方“需要重绘”的视图才会调用draw()方法)。值得说明的是,ViewGroup类已经为我们重写了dispatchDraw()的功能
实现,应用程序一般不需要重写该方法,但可以重载父类函数实现具体的功能。

Google已经帮我们把draw()过程框架已经写好了,自定义的ViewGroup只需要实现
measure()过程和layout()过程即可 。


indivdlite
一般引起invalidate()操作的函数如下:
1、直接调用invalidate()方法,请求重新draw(),但只会绘制调用者本身。
2、setSelection()方法 :请求重新draw(),但只会绘制调用者本身。
3、setVisibility()方法 : 当View可视状态在INVISIBLE转换VISIBLE时,会间接调用invalidate()方法,
继而绘制该View。
4 、setEnabled()方法 : 请求重新draw(),但不会重新绘制任何视图包括该调用者本身。

requestLayout()方法 :会导致调用measure()过程 和 layout()过程 。

说明:只是对View树重新布局layout过程包括measure()和layout()过程,不会调用draw()过程,但不会重新绘制
任何视图包括该调用者本身。

一般指的是设置可见和不可见的时候,会用到

equestFocus()函数说明:
说明:请求View树的draw()过程,但只绘制“需要重绘”的视图。
--------------------------------

熟悉Android的多媒体框架|熟练 | 15


熟悉JNI和NDK的使用,能够实现Java与C之间的互调|熟练 | 24

----------------------------------
熟悉Android下的消息推送,并对相关实现有一定的了解|良好 | 12

 

熟悉Http协议,Socket编程|熟练
Android下的XML,JSON的解析,熟悉Android下的数据存储方式 熟练 |24
Sqlite数据库的应用 熟练 |24

 

熟悉J2EE编程技术,了解Java常用设计模式|熟练 | 15
常见Java设计模式,如单例模式、观察者模式、模板模式 熟练 |24

Linux常用指令 熟练 |12


-----------------------------------------------------------
ListView优化,图片缓存机制 熟练 |24


单张大图的加载:

1.手动干涉vm的处理效率
VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);
2.手动设置vm的大小
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。
当然对于内存吃紧来说还可以通过手动干涉GC去处理

3.手动回收内存
bitmap.recycle();
System.gc()
4.进行一个图片的缩放

5去捕获这个异常,并且换去一个可以使用的图片

6.本地的缓存,
实际上有的时候,我们进行一些加载图片的时候,我们会进行一下本地的缓存,来进行减缓app的线程压力
那么会有 内存缓存 , 硬盘缓存 。我们会根据这些具体的问题来进行一个解决


大量大图的加载
因为android.util.LruCache只能在Android 3.1及更高版本上使用,如果针对版本低于3.1的Android设备,
则仍然必须使用不同的类来实现自己的应用缓存

LRU是Least Recently Used 近期最少使用算法。
内存管理的一种页面置换算法,对于在内存中但又不用的数据块(内存块)叫做LRU,

lrucache是主要去减少oom,因为你要去加载大量的图片,所以你使用lrucache来去管理cacahe图片
主要是缓存管理你的bitmap。
-----------------------------------------------------------
可以解决常见的oom
oom可能的方法是 1.内存泄露 2. 内存不够,使用太多


Android堆内存也可自己定义大小dalvik它的最大堆大小一般是16M
对于一些Android项目,影响性能瓶颈的主要是Android自己内存管理机制问题,
目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对性能的影响十分敏感,
除了 优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的对内存大小,
我们使用Dalvik提供的 dalvik.system.VMRuntime类来设置最小堆内存为例:
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。
当然对于内存吃紧来说还可以通过手动干涉GC去处理

oom:
1.等比例的缩放图片
2.对图片进行软应用,即使的recycle。但是在android2.3之后,软引用不好使!
3对复杂的listview进行合理设计与编码:
1. 注意重用Adapter里面的 convertView 以及holder机制的运用
2. 上述方法尝试还未成功,可用 lazy loading data
4.在页面切换时尽可能少地重复使用一些代码,比如:重复调用数据库,反复使用某些对象等等
5.Android堆内存也可自己定义大小 和 优化Dalvik虚拟机的堆内存分配
注意若使用这种方法:project build target 只能选择 <= 2.2 版本,
否则编译将通不过。 所以不建议用这种方式


对于原因:1.你的代码优化,比如说是你的listview的优化
2.你的cursor没有释放
3.你的 static是Java中的一个关键字,当用它来修饰成员变量时,
那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,
它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(Context的情况最多),
这时就要谨慎对待了

图形对象优化,这里要说的是Android上的Bitmap对象销毁,
可以借助recycle()方法显示让GC回收一个Bitmap对象,通常对一个不用的Bitmap可以使用下面的方式,如
if(bitmapObject.isRecycled()==false) //如果没有回收
bitmapObject.recycle();

-------------------
Android手机的用户,根据习惯不同,可能会有两种方式退出整个应用程序:
一种是按Home键直接退到桌面;另一种是从应用程序的退出按钮或者按Back键退出程序。
那么从系统的角度来说,这两种方式有什么区别呢?按Home键,应用程序并没有被关闭,
而是成为了后台应用程序。按Back键,一般来说,应用程序关闭了,但是进程并没有被杀死,
而是成为了空进程

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。