《Android中高级面试题目整理.pdf》由会员分享,可在线阅读,更多相关《Android中高级面试题目整理.pdf(56页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、一、Java部分1、j a v a 中=和 e q u a l s 和 h a s h Co d e 的区别基本类型:=比较的是值,引用类型:=比较的是内存地址e q u a l s 在没有被覆藕的情况下比较的都是地址h a s h C o d e 比较的是集合,h a s h C o d e 返回的是h a s h 地址2、i n t、c h a r、l o n g 各占多少字节数B y t e:l 个字节,b o o l e a n:至少一个字节,s h o r t:2个字节,c h a r:2个 字 节,i n t:4 个字节,f l o a t:4 个 字 节,l o n g:8 个字
2、节,d o u b l e:8 个字节3、S t r i n g-.S t r i n g Bu f f e r-.S t r i n g Bu i l d e r 区别s t r i n g 对象不可变,后两者是可变:s t r i n g 因为不可变所以线程安全,S t r i n g B u f f e r 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的,S t r i n g B u i l d e r 并没有对方法进行加同步锁,所以是非线程安全的.如何程序不是多线程的,S t r i n g B u i l d e r 效率高于 S t r i n g B u f f
3、e r。4、什么是内部类?内部类的作用在 j a v a 语言中,可以把一个类定义到另外一个类的内部,在类里面的这个类就叫内部类,外面的类就叫外部类.作用:1 .隐藏你不想让别人知道的操作,也即封装性.2.一个内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量!内部类可以分为多种:主要以下4种:静态内部类,成员内部类,局部内部类,匿名内部类态内部类静态内部类是指被声明为s t a t i c 的内部类,他可以不依赖内部类而实例,而通常的内部类需要实例化外部类,从而实例化。静态内部类不可以有与外部类有相同的类名.不能访问外部类的普通成员变量,但是可以访问价态成员变量和静态方法(包括私有
4、类型)成员内部类一个冷态内部类去掉static就是成员内部类,他可以自由的引用外部类的属性和方法.无论是静态还是非静态.但是不可以有静态属性和方法局部内部类定义在一个代码块的内类,他的作用范闱是所在代码块,是内部类中最少使用的一类型.局部内部类跟局部变量一样,不能被public.protected,private以及static修饰,只能访问方法中定义final类型的局部变量匿名内部类匿名内部类是一种没有类名的内部类,不使用class,extends,implements.没有构造函数,他必须继承其他类或实现其他接口.匿名内部类的好处是使代码更加简洁,紧凑,但是带来的问题是易读性下降。5、抽象
5、类和接口区别抽象类,抽象方法必须用abstract关键字进行修饰.如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰.抽象类就是为了继承而存在的如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法.如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。接口;接口中的变量会被隐式地指定为public static final变 量(并且只能是public staticfinal变 量.用private修饰会报编译错误).而方法会被隐式地指定为public abstract方法且只能是public abstract方 法(用其他关键字,
6、比如private,protected,static,final等修饰会报编译错误),并且接口中所仃的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法.区别:抽象类可以提供成G方法的实现细节,而接口中只能存在public abstract方法:抽象类中的成员变量可以是各种类型的,血接口中的成员变量只能是public staticfinal类型:接口中不能含有常态代码块以及静态方法,而抽象类可以有静态代码块和静态方法:一个类只能继承一个抽象类,而一个类却可以实现多个接口.6、算些情况下的对家会被垃圾回收机制处理掉?1.没有引用指向2.只有弱引用指向并且不回收弱引用对象的话存储区无空间
7、3.虚引用指向的对象满足以上任意条件则在g c 时会回收7、讲一下常见编码方式?ASCII、ISO-8859-1 CB2312,CBK,UTF-8、UTF-16 等8、鼻态代理和动态代理的区别,什么场景使用?管态代理:由程序员创建或由特定工具力动生成源代码.再对其编译.在程序运行前,代理类的.c la s s 文件就已经存在了.动态代理;在程序运行时,运用反射机制动态创建而成.10、final,finally,finalize 的区别final:修饰类、成员变fit和成员方法.类不可被黎承,成员变量不可变,成员方法不可重写finally:与 try.catch.共同使用,确保无论是否出现异常都
8、能被调用到finalize:类的方法,坨圾回收之前会调用此方法,子类可以重写fin alize。方法实现对资源的回收11、Serializable 和 Parcelable 的区别Serializable:Ja v a 序列化接口在硬盘上读写读写过程中有大量临时变量的生成,内部执行大量的i/。操作,效率很低.Parcelable:A n d r o i d 序列化接U 效率高使用麻烦在内存中读写(A S 有相关插件一健生成所需方法),对象不能保存到磁盘中12、哪些情况下的对馥会被垃圾回收机制处理掉?1 .所有实例都没有活动线程访问.2 .没有被其他任何实例访问的循环引用实例.3 .J a v
9、a 中有不同的引用类型.判断实例是否符合垃圾收集的条件都依赖户它的引用类型。要判断怎样的对象是没用的对象.这里有2种方法:1 .采用标记计数的方法:给内存中的对象给打上标记,对望被引用一次.计数就加L 引用被群放了.计数就减一,当这个计数为0 的时候,这个对象就可以被回收了.当然,这也就引发了一个问题:循环引用的对象是无法被识别出来并且被回收的.所以就有了第二种方法:2 .采用根搜索算法:从一个根出发,搜索所有的可达对象.这样剩F 的那些对象就是需要被回收的13、说说你对Java反射的理解J A V A 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对冲任意一个对象
10、,都能够调用它的任意一个方法和属性.从对象出发,通过反射(C l a s s 类)可以取得取得类的完整信息(类 名 C l a s s 类型,所在包、具有的所有方法M e t h o d 口类型、某个方法的完整信息(包括修饰符、返回值类型、异常、参数类型)、所有 属 性 F i e l d 口、某个属性的完整信息、构 造 器 C o n s t r u c t o r s),调用类的属性或方法自己的总结:在运行过程中获得类、对象、方法的所有信息。14、Strin g为什么要设计成不可变的?1、字符串池的需求字符串池是方法区(M e t h o d A r e a)中的一块特殊的存储区域.当一个
11、字符串已经被创建并且该字符串在池中,该字符串的引用会立即返回给变量,而不是重新创建一个字符串再将引用返回给变量.如果字符串不是不可变的,那么改变一个引用(如:s t r i n g 2)的字符串将会导致另一个引用(如:s t r i n g l)出现脏数据。2、允许字符串级存哈希码在 j a v a 中常常会用到字符串的哈希码,例如:H a s h M a p .St r i n g 的不变性保证哈希码始终一,因此,他可以不用担心变化的出现。这种方法意味着不必每次使用时都重新计算一次哈希码一这样,效率会高很多.3、贻St r i n g 广泛的用于j a v a 类中的参数,如:网络连接(N
12、e t w o r k c o n n e t i o n),打开文件(o p e n i n g f i l e s )等等。如果St r i n g 不是不可变的,网络连接、文件将会被改变这将会导致一系列的安全威胁.操作的方法本以为连接上了一台机器,但实际上却不是.由F 反射中的参数都是字符串,同样,也会引起一系列的安全问题.1 5、L i s t,Se t,M a p 的区别S e t,是最简单的一种集合。集合中的对望不按特定的方式排序,并且没有重复对象。S e t接口主要实现了两个实现类:H a s h S e t:H a s h S e t 类按照哈希算法来存取集合中的对象.存取速度
13、比较快T r e e S e t ,T r e e S e t 类实现了 S o r i e d S e t 接口,能够对集合中的对象进行排序.L i s t 的特征是其元素以线性方式存储,集合中可以存放重旦对象。A r r a y L i s t O :代表长度可以改变得数组。可以对元素进行随机的访问,向A r r a y L i s t O中插入与删除元素的速度慢.L i n k e d L i s t O:在实现中采用链表数据结构.插入和射除速度快,访问速度慢.M a p:是一种把维对象和值对象映射的集合.它的每一个元素都包含一对健对象和值对象.M a p 没有继承于C o l l e
14、c t i o n 接 口 从 M a p 集合中检索元素时,只要给出键对象,就会返回对应的值对象.H a s h M a p,M a p 基于散列表的实现.插入和查询“键值对”的开销是固定的.可以通过构造器设置容量c a p a c i t y 和负载因子l o a d f a c t o r,以调整容器的性能.L i n k e d H a s h M a p:类似于H a s h M a p,但是迭代遍历它时,取 得“键值对”的顺序是其插入次序,或者是最近/少使用(L R I)的次序。只比H a s h M a p 慢一点.而在迭代访问时发问更快.因为它使用链表维护内部次序.T r e
15、e M a p t 基于红黑树数据结构的实现.查看“键”或“键值对”时,它们会被排序(次序由C o m p a r a b e l 或 C o m p a r a t o r 决 定).T r e e M a p 的特点在 于,你得到的结果是经过排序的.T r e e M a p 是唯一的带有s u b M a p()方法的M a p,它可以返回一个子树.V e a k H a s b M a o:弱键(w e a k k e y)M a p,V a p 中使用的对象也被允许新放:这是为解决将殊问题设计的.如果没有m a p 之外的引用指向某个“键”.则 此“键”可以被境圾收集器回收.1 6、
16、A rra y L i s t 和 L i n k e d L i s t 的区别,以及应用场景A r r a y L i s t;是基广数组实现的,A r r a y L i s t 线程不安全.L i n k e d L i s t.是基于双链表实现的:使用场都(1)如果应用程序对各个索引位置的元素进行大量的存取或删除操作,A r r a y L i s t 对象要远优于L i n k e d L i s t 对象:(2)如果应用程序主要是对列表进行循环,并且循环时候进行插入或者删除操作,L i n k e d L i s t 对象要远优于A r r a y L i s t 对较;1 7、
17、数组和健表的区别数组:是将兀素在内存中连续存储的:它的优点:因为数据是连续存储的,内存地址连续,所以在查找数据的时候效率比较高:它的缺点:在存储之前,我们需要申请一块连续的内存空间,并且在编译的时候就必须确定好它的空间的大小.在运行的时候空间的大小是无法随着你的需要进行增加和减少而改变的.当数据两比较大的时候,仃可能会出现越界的情况,数据比较小的时候,又有可能会浪费掉内存空间。在改变数据个数时,增加、插入、删除数据效率比较低.健表:是动态申请内存空间,不需要像数组需要提前申请好内存的大小.链表只需在用的时候申请就可以,根据需要来动态申请或者删除内存空间,对于数据增加和删除以及插入比数组织活.还
18、有就是链表中数据在内存中可以在任意的位置,通过应用来关联数据(就是通过存在元素的指针来联系)1 8、r u n()和 s t ar t。方法区别这个问题经常被问到,但还是能从此区分出面试者对Java线程模型的理解程度.start 0方法被用来启动新创建的线程,而且start。内部调用了 run。方法,这和直接调用run。方法的效果不一样.当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动.start。方法才会自动新线程.1 9、如何控制某个方法允许并发访问线程的个数?semaphore,acquire0请求一个信号量,这时候的信号量个数T(一旦没有可使用的信号S.也即信号
19、量个数变为负数时,再次请求的时候就会阳塞,直到其他线程释放了信号量)semaphore,release()郛放一个信号量,此时信号量个数+12 0、在 J av a中w ai t 和 s e e l p 方法的不同Java程序中w ait和sleep都会造成某种形式的暂停,它们可以满足不同的需要.waitO方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会弹放锁,而sleep。方法仅仅秆放CPU资源或者让当前线程停止执行一段时间,但不会群放锁.2 1、谈谈w ai t/n o t i f y 关健字的理解等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则编译可以通过,但运
20、行时会收到一个异常:11 legalMonitorStateException.调用任意对象的w aitO方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被择放.唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级.调用任意对象的n o t i f y。方法则导致因调用该对象的w a i t。方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。2 2、什么导致线程阻塞?线程如何关闭?阻塞式方法是指程序会一直等待该方法完成期间不做其他事情,S e
21、 r v e r S o c k e t 的 a c c e p t 0方法就是一直等待客户端连接.这里的阻塞是指调用结果返回之前,当前线程会被挂起.直到得到结果之后才会返回.此外,还有异步和非阴塞式方法在任务完成前就返回.一种是调用它里面的s t o p。方法另一种就是你自己设重一个停止线程的标记(推荐这种)2 3、如何保证线程安全?1.s y n c h r o n i z e d;2.O b j e c t 方法中的 w a i t,n o t i f y:3.T h r e a d L o c a l 机制来实现的.2 4、如何实现线程同步?1、s y n c h r o n i z
22、e d 关键字修改的方法。2、s y n c h r o n i z e d 关键字修饰的语旬块3、使用特殊域变量(v o l a t i l e)实现线程同步2 5、淡淡对S y nc hroniz e d 关健字,类锁,方法锁,重入锁的理解j a v a 的对象锁和类镇,j a v a 的时象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用尸类的静态方法或者一个类的c l a s s 对象上的.我们知道,类的对毂实例可以有很多个,但是每个类只有一个c l a s s 对望,所以不同对象实例的对象锁是互不干
23、扰的,但是每个类只有一个类锁.但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的2 6、s y nc hroniz e d 和 v ola t ile 关健字的区别1.v o l a t i l e 本质是在告诉j v m 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取:s y n c h r o n i z e d 则是锁定当前变量,只有当前线程可以访问该变量.其他线程被阻塞住.2.v o l a t i l e 仅能使用在变量级别:s y n c h r o n i z e d 则可以使用在变量、方法
24、、和类级别的3.v o l a t i l e 仅能实现变量的修改可见性,不能保证原子性:而 s y n c h r o n i z e d 则可以保证变量的修改可见性和原子性4.v o l a t i l e 不会造成线程的阻塞:s y n c h r o n i z e d 可能会造成线程的阴塞.5.v o l a t i l e 标记的变量不会被编译器优化:s y n c h r o n i z e d 标记的变量可以被编译器优化2 7、R e e nt ra nt Loc k、s y nc hroniz e d 和 v ola t ile 比较ava在过去很长一段时间只能通过synch
25、ronized关键字来实现互斥,它有一些缺点.比如你不能扩展锁之外的方法或者块边界,尝试获取锁时不能中途取消等.Java 5通过Lock接口提供了更复杂的控制来解决这些问题.ReentrantLock类实现了 Lock,它拥有与synchronized相同的并发性和内存语义且它还具有可扩展性.2 8、死做的四个必要条件?死镇产生的原因1.系统费源的竞争系统资源的竞争导致系统资源不足,以及资源分配不当,导致死锁.2.艇运行不神互斥条件,一个资源每次只能被一个进程使用,即在一段时间内某资源仅为一个进程所占有.此时若有其他进程请求该资源,则请求进程只能等待.请求与保持条件:进程已经保持了至少一个资源
26、.但乂提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对白己已获得的资源保持不放.不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程1*1己来绛放(只能是主动糅放).循环等待条件:若干进程间形成首尾相接循环等待资源的关系这四个条件是死锁的必要条件,只要系统发生死锁.这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。死健的重兔与预防,死依雉克的基本思想:系统对进程发出每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,如果分配后系统可能发生死锁,则不予分配,否则予以分配.这是一种保证系统不进入死锁状
27、态的动态策略。理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁.所以.在系统设计、进程调度等方面注意如何让这四个必要条件不成立,如何确定资源的合理分配算法,避免进程永久占据系统资源.此外,也要防止进程在处于等待状态的情况下占用资源.因此.时资源的分配要给予合理的规划.死锁重兔和死(预防的区别:死锁预防是设法至少破坏产生死锁的四个必要条件之一,严格的防止死锁的出现,而死锁避免则不那么严格的限制产生死锁的必要条件的存在,因为即使死锁的必要条件存在,也不一定发生死锁.死锁避免是在系统运行过程中注意避免死锁的最终发生.2 9、什么是线程池,如何使用?创建线程要花费昂
28、贵的资源和时间.如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题.在程J节启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程.从JDK1.5开始,Java API提供了 E x e c u t o r 框架让你可以创建不同的线程池.比如单线程池,每次处理一个任务:数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)。30、Java中堆和栈有什么不同?为什么把这个问题归类在多线程和并发面试题里?因为栈是一块和线程紧密相关的内存区域。每个线程都有力己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程
29、中存储的变量对其它线程是不可见的而堆是所有线程共享的一片公用内存区域.对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到力己的栈,如果多个线程使用该变量就可能引发问题,这时v o l a t i l e 变量就可以发挥作用了,它要求线程从主存中读取变量的值.31、有三个线程TL T2,T 3,怎么确保它们按顺序执行?在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的j o i n。方法在一个线程中扇动另一个线程,另外一个线程完成该线程继续执行.为了确保三个线程的顺序你应该先启动最后一个(T 3调用T 2,T 2 调用T 1).这样T I 就会先完成而T 3最后完成.线程间通信我们知
30、道线程是C P U 调度的最小单位。在 A n d r o i d 中主线程是不能够做耗时操作的.子线程是不能够更新U I 的.而线程同通信的方式有很多,比如广播.E v e n t b u s,接口回掉,在A n d r o i d 中主要是使用h a n d l e r。h a n d l e r 通过调用s e n d m e s s a g e 方法,将保存消息的M e s s a g e 发送到M e s s a g e q u e u e 中,而 l o o p e r 对象不断的调用l o o p 方法,从 m e s s a g e u e u e中取出m e s s a g
31、e,交给h a n d l e r 处理,从而完成线程间通信。32、说下你对Collection这个类的理解.C o l l e c t i o n 是集合框架的顶层接U,是存储对象的容器,C o l l o c t i o n 定义了接口的公用方法如a d d r e m o v e c l e a r 等等,它的子接口有两个.L i s t 和 S e t,L i s t 的特点有元素有序,元素可以重复,元素都有索引(角标),典型的有V e c t o r:内部是数组数据结构,是同步的(线程安全的).增删查询都很慢.A r r a y L i s t:内部是数组数据结构,是不同步的(线程不
32、安全的).替代了 V e c t o r.查询速度快,增删比较慢.L i n k e d L i s t:内部是链表数据结构,是不同步的(线程不安全的).增删元素速度快。血S e t 的是特点元素无序,元素不可以重复H a s h S e t:内部数据结构是哈希表.是不同步的.S e t 集合中元素都必须是唯一的,H a s h S e t 作为其子类也需保证元素的唯一性.判断元素唯一性的方式:通过存储对象(兀素)的 h a s h C o d e 和 e q u a l s 方法来完成对象唯一性的.如果对象的h a s h C o d e 值不同,那么不用调用e q u a l s 方法就会
33、将对象直接存储到集合中:如果对象的h a s h C o d e 值相同,那么需调用e q u a l s 方法判断返回值是否为t r u e.若为f a l s e,则视为不同元素,就会直接存储:若 为 t r u e.则视为相同元素,不会存储.如果要使用Ha s h S e t 集合存储元素,该元素的类必须覆盖h a s h C o d e 方法和e q u a l s 方法.一般情况下,如果定义的类会产生很多对象.通常都需要覆蛊e q u a l s.h a s h C o d e 方法.建立对象判断是否相同的依据.T r e e S e t:保证元素唯一性的同时可以对内部元素进行排序,
34、是不同步的.判断元素唯一性的方式:根据比较方法的返回结果是否为0,如果为0视为相同元素,不存:如果非0视为不同元素,则存.T r e e S e t 对元素的排序有两种方式:方式一:使 元 素(对象)对应的类实现C o m p a r a b l e 接口,覆蛊c o m p a r e T o 方法.这样元素门身具有比较功能。方式二:使 T r e e S e t 集合白身具有比较功能.定义一个比较器C o m p a r a t o r,将该类对象作为参数传递给T r e e S e t 集合的构造函数2、Android 部分1、Activity各种情况下的生命周期Si tua ti on
35、l:正常启动:onCreateOonStart()onResume0:返回健退出:onPauseOonStopO-onDestory():Si tua ti on2:正常自动:o nC r e a t e O -*o nS t a r t -*0 o nR e s u m e();按 h o m e 健:o nP a u s e O o nS t o p O ;正常启动:o nR e s t a r t 0 -o nS t a r t ()-*o nR e s u m e ();S it u a t io ns:正常启动:o nC r e a t e O o nS t a r t ()-*o
36、nR e s u m e ();横竖屏切换:o nP a u s e O -*o nS t o p O o nD e s t o r y O o nC r e a t e O -o nS t a r t()-o nR e s u m e 0;S it u a t io n4:前提条件:A c t iv it y 的 A nd r o id M a nif e s t.x m l 中设置a nd r o id:c o nf ig C h a ng e s=*o r ie nt a t io n|ke y b o a r d l l id d e n|s c r e e ns iz e”正常启动:
37、o nC r e a t e O -*o nS t a r t 0 -o nR e s u m e();横竖屏切换:o nC o nf ig u r a t io nC h a ng e d O :结论,设置 A c t iv it y 的 a nd r o id:c o nf ig C h a ng e s=*o r ie nt a t io n|ke y b o a r d Hid d e n|s c r e e nS iz e*时,切屏不会重新调用各个生命周期,只会执 行 o nC o nf ig u r a t io nC h a ng e d 方法:自从 A nd r o id 3.
38、2 (A P I 1 3),在设置 A c t iv it y 的 a nd r o id:c o nf ig C h a ng e s=*o r ie nt a t io n|ke y b o a r d Hid d e n 后,还是一样会重新调用各个生命周期的.因为s c r e e ns iz e 也开始跟着设备的横轻切换而改变。所以,在 A nd r o id M a nif e s t.x m l 里设置的M iniS d kV e r s io n和T a r g e t S d kV e r s io n属性大于等于1 3 的情况F,如果你想阻止程序在运行时重新加载A c t i
39、v it y,除了 设置 o r ie nt a l io n,你还必须设置 S c r e e nS iz e”。2、横竖屏切换的时候,A ctivity各种情况下的生命周期分两种情况:1.不设置 A c t iv it y 的 a nd r o id:c o nf ig C h a ng e sr 或设置 A c t iv it y 的a nd r o id:c o nf ig C h a ng e s=*o r ie nt a t io n*.或设置 A c t iv it y 的a nd r o id:c o nf ig C h a ng e s=*o r ie nt a t io n
40、|ke y b o a r d Hid d e n*切屏会重新调用各个生命周期,切横屏时会执行一次切竖屏时会执行一次。横竖屏切换造成a c t iv it y 的生命周期o nP a u s e()-o nS a v e I ns t a nc e S t a t e 0-o nS t o p()-o nD e s t r o y()-o nC r e a t()-o nS t a r t()一o nR e s t o r e I ns t a nc e S t a t e()-o nR e s u m e()即会导致 a c t iv it y 的销毁和重建.2.fid置 android:c
41、onfigChanges=*orientation|keyboardHidden|screenSize*才不会销毁 a c tiv ity,且只调用 onConfiguraiionChanged 方法。onSave I ns t anceS t a t e()与onRestorelntanceStateO资源相关的系统配置发生改变或者资源不足时(例如屏幕旋转),当 前A ctivity会销毁,并且在onSlop之前回调onSavelnstanceState保存数据,在重新创建A ctivity的时候在onSlarl之后回调onRestorelnstanceStateo 其中 Bundle 数据
42、会传到 onCreaie(不一定有数据)和onRestore I nstanceStat e(一定有数据).用户或者程序员主动去销毁一个A ctivity的时候不会回调(如代码中finish()或用户按卜.back,不会回调),其他情况都会调用,来保存界面信息.3、Activity与Fragment之间生命周期比较Activity StateFragment CallbacksCreatedonAttach()onCreate()onCreateView()onActivityCreatedOResumedonResumeOStartedonStart()PausedonPauseQStopp
43、edonStopf)DestroyedonDestroyVewQonDestroyOonDetach()4、两个A c tiv ity之间跳转时必然会执行的是哪几个方法?一般情况下比如说有两个a c t i v i t y,分别叫A,B.当在A 里面激活B 组件的时候,A会调用 o n P a u s e O 方法,然后 B 调用 o n C r e a t e O ,o n S t a r t (),o n R e s u m e 0.这个时候 B 漫蛊了A的 窗 体,A会调用o n S i o p O 方 法.如 果 B是个透明的窗口,或者是对话框的样式,就不会调用A的 o n S t o
44、 p O 方 法.如 果 B已经存在于A c t i v i t y 栈中,B就不会调用o n C r e a t e O 方法.5、内存泄漏的场景和解决办法1 .非静态内部类的静态实例非静态内部类会持有外部类的引用,如果非静态内部类的实例是静态的,就会长期的维持着外部类的引用,组织被系统回收,解决办法是使用静态内部类2.多线程相关的匿名内部类和非静态内部类匿名内部类同样会持有外部类的引用,如果在线程中执行耗时操作就有可能发生内存泄漏,导致外部类无法被回收,直到耗时任务结束,解决办法是在页面退出时结束线程中的任务3.H a n d l e r 内存泄漏H a n d l e r 导致的内存泄漏
45、也可以被归纳为非静态内部类导致的.H a n d l e r 内部m e s s a g e 是被存储在M e s s a g e Q u e u e 中的,有些m e s s a g e 不能马上被处理,存在的时间会很长,导致h a n d l e r 无法被回收,如果h a n d l e r 是非静态的,就会导致它的外部类无法被回收.解决办法是1.使用静态h a n d l e r,外部类引用使用弱引用处理2.在退出页面时移除消息队列中的消息4 .C o n t e x t 导致内存i f t 漏根据场景确定使用A c t i v i t y 的 C o n t e x t 还是A p
46、p l i c a t i o n 的 C o n t e x t,因为二者生命周期不同,对于不必须使用A c t i v i t y 的 C o n t e x t 的 场 景(D i a l o g),一律采用A p p l i c a t i o n 的C o n t e x t.单例模式是最常见的发生此泄漏的场景,比如传入一个A c t i v i t y 的 C o n t e x t 被静态类引用,导致无法回收5.静态V i e w 导致泄漏使用静态V i e w 可以避免每次扇动A c t i v i t y 都去读取并渲染V i e w,但是静态V i e w 会持有A c t
47、 i v i t y 的引用,导致无法回收,解决办法是在A c t i v i t y 销毁的时候将静态V i e w 设置为n u l l (V i e w 一旦被加载到界面中将会持有一个C o n t e x t 对象的引用,在这个例子中,这个c o n t e x t 对象是我们的A c t i v i t y,声明一个静态变量引用这个V i e w,也就引用了a c t i v i t y)6.W e b V i e w 导致的内存泄漏呢b V i e w 只要使用一次,内存就不会被林放.所以W e b V i e*都存在内存泄漏的问题,通常的解决办法是为W e b Y i e w 单
48、开一个进程,使用A I D L 进行通信,根据业务需求在合适的时机料放掉7 .资源对象未关闭导致如C u r s o r,F i l e 等,内部往往都使用了缓冲,会造成内存泄漏,一定要确保关闭它并将引用置为n u l l8 .集合中的对象未清理集合用于保存对蒙,如果集合越来越大,不进行合理的清理,尤其是入股集合是静态的9 .B i t m a p 导致内存泄漏b i t m a p 是比较占内存的,所以一定要在不使用的时候及时进行清理,避免静态变量持有大的 b i t m a p 对象10.监听器未关闭很多需要re g is te r和 unregister的系统服务要在合适的时候进行unr
49、egisier,下动添加的 lis te n e r也需要及时移除6、如何避免00M?1.使用更加轻量的数据结构:如使用ArrayMap/SparseArray替代HashMap,HashMap更耗内存,因为它需要额外的实例对象来记录Mapping操 作,SparseArray更加高效.因为它避免了 Key Value的白动装箱,和装箱后的解箱操作2.便面枚举的使用,可以用静态常量或者注解IniDef替代3.Bitmap 优化:a.尺寸压缩:通 过 InSampleSize设置合适的缩放b.颜色质量:设置合适的 format,ARGB_6666/RBG_545/ARGB_4444/ALPHA_
50、6,存在很大差异c.inBitmap:使 用 inBitmap属性可以告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的Bitmap会尝试去使用之前那张Bitmap在 Heap中所占据的pixel d a ta 内存区域,而不是去问内存重新中清一块区域来存放B itm ap.利用这种特性,即使是上千张的图片.也只会仅仅只需要占用屏幕所能够显示的图片数量的内存大小,但复用存在一些限制,具体体现在:在 Android 4.4 之前只能重用相同大小的Bitmap的内存,而Android 4.4 及以后版本则只要后来的Bitmap比之前的小即可。使用inBitmap参数前,每创建一个Bitm