java
数据类型
-
基本数据类型
数值型:byte(8),short(16),int(32),long(64),float(32),double(64)
字符型:char(16)
布尔类型:boolean(8)
引用数据类型:String, 数组, 对象的引用
String, StringBuffer, StringBuilder
三者在执行速度方面的比较:StringBuilder > StringBuffer > String
StringBuilder:线程非安全的
StringBuffer:线程安全的
对于三者使用的总结:
1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer-
类型转换
- 隐式:byte->short->int->long->float->double
- 强制类型:高精度转低精度的时候,会无条件去除多余的位
封装类型常量池:除了float和double,其他的基本数据类型的封装类型都有一个常量池,-128到127之前
集合
- set
使用元素的equals进行比较,返回true就代表相同,不允许存入两个相同的元素,允许存入null;
HashSet:不保证元素的顺序,每次Hash的结果都是不一样的,可以存null,通过equals和hashCode()判断两个元素是否相等,
LinkedHashSet:使用链表将HashSet的元素维护起来,让元素顺序看起来和插入的顺序一样,迭代访问时性能较好,插入时性能较差
TreeSet:使用CompareTo方法将元素按照升序排序
- map
HashMap
底层结构式Hash表,无序,线程不安全
TreeMap
底层结构式二叉树,有序,线程不安全
内存回收:
引用计数器、占位算法、移位更新
引用类型
- 强引用,只要对被强引用,则对象不会销毁, 内存不够用时,程序崩溃
- 软引用,被软引用引用的对象在内存不够用时会被销毁。
- 弱引用,被弱引用引用的对象在被扫描时会被销毁。
- 虚引用,随时被销毁。
线程同步
- synchronized:对同一进程中的某一资源加锁,同一时刻只允许一个线程对这个资源进行操作
- obj.wait():释放对obj的锁,同时自身进入休眠状态,知道被其他线程唤醒
- obj.notify():通知其他另一个正在等待obj资源的线程可以醒来了,我正在用,等下用完了交给你
- volatile:声明一个随时都在变化的内存,当多个线程都在对一个变量进行操作的时候,线程会把这个变量copy一份的线程在栈中的工作内存,操作完之后再把这个值交给堆内存(各个线程共享的内存)
设计原则
- 单一职责:一个类里面只实现这个类应该实现的功能
- 里氏替换:子类拓展父类的时候,尽量不要重写已经实现的方法,用接口去替换
- 依赖倒置:用更多的接口去描述大致相同但具体实现不同的动作,降低耦合度
- 接口隔离:多用子接口去实现出不同的功能,将想要拓展功能的类和功能接口尽量隔离开,降低耦合
- 开闭原则:对使用接口开放,对修改实现关闭
设计模式
创建型模式
- 工厂方法
- 抽象工厂
- 单例模式
- 建造者模式:Dialog,一个类如果成员变量太多,在构造对象的时候就可以使用建造者模式
- 原型模式
结构型模式
- 适配器模式:让两个互不相干的接口或类通过公共的一个类进行适配对接。
- 装饰器模式:装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,需要动态扩展的时候使用
- 代理模式:中介和房东实现同一个接口,中介持有房东对象,但是可以让租房过程更加规范专业,租客调用中介的方法就行了,跟装饰器差不多。
- 外观模式:为了解决类与类之间的依赖关系,只有一个公共的类持有其他类的对象。
- 桥接模式:如果一个功能需要不同的实现细节,那么可以多个不同的类实现这些细节,创建一个桥对象持有这个功能对象,然后为桥设置不同的细节类,只需要调用桥的功能方法就可以了
- 组合模式:
行为型模式
- 策略模式:各个子类不同的实现父类接口,接口隔离依赖倒置
- 模板模式:在父类中调用子类重写的方法
- 观察者:多个观察者实现一个观察方法,一个管理观察者的类可以增删观察者和调用所有观察者的观察方法去更新信息,然后功能类要执行某个操作的同时通知所有观察者的话就需要继承这个观察者的管理类。Android中广播,按钮的add什么Listener基本上都可以理解为观察者
- 原型模式:一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。Intent
Android
Activity启动过程
App进程通知AMS启动Activity-->进入系统进程处理,通知上一个Activity的ApplicationThread进行pause-->进入App进程,pause完成后,通知AMS-->进入系统进程处理,通知App的ApplicationThread进行scheduleLaunchActivity --> 进入App进程,创建Activity对象,调用Activity.onCreate()、onStart()、onResume(),通知AMS-->进入系统进程处理,通知上一个App的ApplicationThread进行stop
ListView回收机制
Android本身对ListView是做过优化的,查看源码我们可以发现AbsListView类当中有一个内部类——RecycleBin,和一个接口RecyclerListener。ListView中所包含的所有子View被分为“mActiveViews”“mScrapViews”两个部分,前者是当前活动的,也就是屏幕上显示的Views,后者是不可见的Views。如果实现了RecyclerListener接口,当一个View由于ListView的滑动被系统回收到RecycleBin的mScrapViews数组时,会调用RecyclerListener中的onMovedToScrapHeap(View view)方法。RecycleBin相当于一个临时存储不需要显示的那部分Views的对象,随着列表滑动,这些Views需要显示出来的时候,他们就被从RecycleBin中拿了出来,RecycleBin本身并不对mScrapViews中的对象做回收操作。
于是在工程里,为ListView添加RecyclerListener接口,并在onMovedToScrapHeap方法中释放ListItem包含的Bitmap资源,这样可以极大的减少内存占用。
ANR
Application Not Responding
Activity:5s
Broadcast:10s
Service:15s
Activity启动模式何时应用
可以根据实际的需求为Activity设置对应的启动模式,从而可以避免创建大量重复的Activity等问题。
组件之间数据通信的几种方式
Intent, Bundle, File, Sqlite, SharedPereffrence,广播,Binder,ContentProvider
Application Context和Activity Context的异同
在使用context的时候,小心内存泄露,防止内存泄露,注意一下几个方面:
不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的
对于生命周期长的对象,可以使用application context
避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化
线程之间通信
- Handler+Looper+MessageQueue之间关系
- Handler内存泄漏:
http://blog.csdn.net/zhuanglonghai/article/details/38233069 - AsyncTask:内部有线程池对任务进行管理,线程对象放在队列里面,队列大小128,这里面的线程池分两种,异步和同步,核心任务5个,
- AsyncTask联网?能否并发100个
- AsyncTask与Activity生命周期问题
如果你在一个Activity中创建了一个AsyncTask,你旋转了屏幕,这个Activity将会被销毁并且会重新创建一个新的实例。但是AsyncTask没有销毁,它将会继续执行直到完成。当它执行完成后,它实际上是更新了上一个已经不存在的Activity,如果你原本想在onPostExecute()中更新UI的话,这时的AsyncTask将不会更新新的Activity
- AsyncTask内存泄露问题
在Activity中作为内部类创建AsyncTask很方便。因为AsyncTask在执行完成或者执行中需要使用Activity中的view,因为内部类可以直接访问外部类的域(也就是变量)。然而这意味着内部类会持有外部类的一个引用。
当长时间运行时,因为AsyncTask持有Activity的引用,所以即使当该Activity不再显示时Android也无法释放其占用的资源。
View事件分发
http://www.cnblogs.com/linjzong/p/4191891.html
当一个Touch事件(触摸事件为例)到达根节点,即Acitivty的ViewGroup时,它会依次下发,下发的过程是调用子View(ViewGroup)的dispatchTouchEvent方法实现的。简单来说,就是ViewGroup遍历它包含着的子View,调用每个View的dispatchTouchEvent方法,而当子View为ViewGroup时,又会通过调用ViwGroup的dispatchTouchEvent方法继续调用其内部的View的dispatchTouchEvent方法。dispatchTouchEvent方法只负责事件的分发,它拥有boolean类型的返回值,当返回为true时,顺序下发会中断。在上述例子中如果⑤的dispatchTouchEvent返回结果为true
ViewGroup的相关事件有三个:onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent。View的相关事件只有两个:dispatchTouchEvent、onTouchEvent。
ViewGroup的dispatchTouchEvent是真正在执行“分发”工作,而View的dispatchTouchEvent方法,并不执行分发工作,或者说它分发的对象就是自己,决定是否把touch事件交给自己处理,而处理的方法,便是onTouchEvent事件.
一般情况下,我们不该在普通View内重写dispatchTouchEvent方法,因为它并不执行分发逻辑。当Touch事件到达View时,我们该做的就是是否在onTouchEvent事件中处理它。
那么,ViewGroup的onTouchEvent事件是什么时候处理的呢?当ViewGroup所有的子View都返回false时,onTouchEvent事件便会执行。由于ViewGroup是继承于View的,它其实也是通过调用View的dispatchTouchEvent方法来执行onTouchEvent事件。
在目前的情况看来,似乎只要我们把所有的onTouchEvent都返回false,就能保证所有的子控件都响应本次Touch事件了。但必须要说明的是,这里的Touch事件,只限于Acition_Down事件,即触摸按下事件,而Aciton_UP和Action_MOVE却不会执行。事实上,一次完整的Touch事件,应该是由一个Down、一个Up和若干个Move组成的。Down方式通过dispatchTouchEvent分发,分发的目的是为了找到真正需要处理完整Touch请求的View。当某个View或者ViewGroup的onTouchEvent事件返回true时,便表示它是真正要处理这次请求的View,之后的Aciton_UP和Action_MOVE将由它处理。当所有子View的onTouchEvent都返回false时,这次的Touch请求就由根ViewGroup,即Activity自己处理了。
View绘制过程
- onMeasure
MeasureSpec.AT_MOST
MeasureSpec.EXACTLY
MeasureSpec.UNSPECIFIED - onLayout
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
// 动态获取子View实例
for (int i = 0, size = getChildCount(); i < size; i++) {
View view = getChildAt(i);
// 放置子View,宽高都是100
view.layout(l, t, l + 100, t + 100);
l += 100 + padding;
}
}
- onDraw
图片操作
动画
- Tween动画
- java代码使用Animation四个四类操作
- xml中使用几个标签操作
- Frame动画
- 按时间轮播图片
Http
http://www.cnblogs.com/ranyonsue/p/5984001.html
TCP/IP & UDP
- 区别
首先,TCP/IP 和UDP最大的区别就是:TCP/IP是面向连接的,UDP是非面向连接的。通俗一点说就是:TCP/IP管发管到,UDP管发不管到。因此,在安全性方面来说,TCP/IP更具有优越性。
第二:TCP/IP偏重的是点对点的通信,使用时服务器和客户端的区别显而易见,而UDP则可以使用组播实现一对多,通信时更像一个群聊系统,几乎没有客户端和服务器的区别,在时间和空间上具有更高的节约性。使用组播时,确定一个D类地址作为组的地址,将本机加入组中,向组内发送消息,从组中接收消息。
第三:在具体编写的代码结构上,TCP/IP是通过创建Socket对象进行连接,从连接对象上得到输入输出流,在流中读写从而通信。而UDP则是在本机创建DatagramSocket对象,将数据包装成DatagramPacket包来发送,其中包里有要发送到的地址。
- TCP/IP的三次握手
Client -> Server : SYN,向服务器发送请求信号
Server -> Client : SYN+ACK,返回客户端发来的请求信号和自己的应答信号
Client -> Server :SYN=0,ACK,返回空的请求信号和服务器发过来的响应信号内容 - TCP/IP的四次挥手
断开的连接的开始一方可以是Client也可以是Server
A -> B : FIN,数据终止信号,希望断开连接;
B -> A : ACK,返回确认信号,但是B端可能还在处理数据;
B -> A : FIN,B端处理完成之后向A端发送可以断开连接的信号;
A -> B : ACK,确认信号,断开连接;
XML解析方式
- dom,一次性把xml所有内容存入内存,然后以树的形式进行解析,费内存,不占CPU
- sax,将读入的XML内容作出相应的响应事件,在事件中进行处理
- pull,跟sax差不多,但是没有事件推动,需要自己写事件
四大组件
- Activity
- BroadcastResevicer
- Server
- ContentProvider
Android内存优化
- 避免OOM
OOM的类型: - 图片OOM
- 内存大的引用被生命周期很长的类持有
Static Activities:把当前Activity的引用副职给了一个静态的Activity,导致当前Acivity应该销毁的时候,却因为还有引用被持有而不被销毁。
Static Views:跟上面差不多
Inner Classes:跟上面差不多
Anonymous Classes:跟上面差不多
Handler:Activity该销毁了,但是消息队列中的消息没有处理完,就会内存泄露,因为handMessage里面持有Activty的隐式引用
Threads:跟上面差不错
TimerTask:跟上面差不多
Sensor Manager:获取系统的这些服务的时候,这些服务会持有Context
- 图片OOM处理:压缩、及时回收、软引用、LruCache
图片缓存
- 二级缓存(三级缓存)
Fragment
-
生命周期
- getActivity == null
http://blog.csdn.net/chu_cheng/article/details/53329822
http://blog.csdn.net/u010603896/article/details/49618123