Q1:android:layout_weight的真实含义
解答:首先声明只有在Linearlayout中,该属性才有效。之所以android:layout_weight会引起争议,是因为在设置该属性的同时,设置android:layout_width为wrap_content和match_parent会造成两种截然相反的效果。
android:layout_weight的真实含义是:一旦View设置了该属性(假设有效的情况下,那么该 View的宽度等于原有宽度(android:layout_width)加上剩余空间的占比。
详见:android:layout_weight的真实含义
Q2:线性布局中如何按比例显示子控件?
如果线性布局是垂直,子控件设置属性android:layout_height=“0”,然后使用android:layout_weight可以按比例显示子控件。
Q3:打开一个应用,返回桌面,然后再次返回应用,activity分别经历了怎么样的生命周期?
打开一个应用,调用 onCreate()->onStart()->onResume();
“退到后台”或“跳转下一个页面”调用 onPause()->onStop();
再次打开应用 onRestart()->onStart()->onResume();
Q4:equals和==的区别
== 等于,equals相同
如果比较对象是值变量,只能用==,equals是不存在的。
如果比较对象是引用型变量:
==:比较两个引用是不是指向同一个对象实例。
equals:比较两个引用指向的对象实例的值是不是相同。
参考如何“记住” equals 和 == 的区别?
Q5:switch能够使用String做参数?
在Jdk1.7之前只支持byte,short,int,char或者对应的封装类以及Enum类型,不支持String和long类型。
在Jdk1.7中加入String支持,String不能传null做参数,同时case语句中使用的字符串也不能为null,因为底层是通过equals和hashmap实现的。
Q7:java中的四种引用
从jdk1.2版本开始,把对象的引用分为四种级别,这四种级别由高到低依次为:强引用,软引用,弱引用和虚引用。
1强引用:
如果一个对象具有强引用,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会回收具有强引用的对象来解决内存不足问题。如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话JVM在合适的时机就会回收该对象。
2 软引用:
如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,软引用就会被垃圾回收器回收。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
3 弱引用
具有弱引用的对象拥有更短暂的生命周期。因为当JVM进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收,不过垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
4 虚引用
“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。
虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
Q10:什么是ANR问题,为什么会引起ANR?
ANR Application Not Response应用程序无响应。
1) 在Service后台执行耗时操作。
2) BroadcastReceiver的onReceiver方法中执行耗时操作。
3) 应用程序可以接收输入事件(按键、触屏、轨迹球等),当5秒内没有处理完毕时,则会引发ANR。
ANR机制以及问题分析https://duanqz.github.io/2015-10-12-ANR-Analysis
Q11:主线程中的Looper.loop()一直无限循环为什么不会造成ANR
参考:来自http://www.jianshu.com/p/cfe50b8b0a41
正如我们所知,在Android中如果主线程中进行耗时操作会引发ANR异常。
造成ANR的原因一般有两种:
1 当前的事件没有机会得到处理(即主线程正在处理一个事件,没有及时地完成或者looper被某种原因阻塞住了)
2 当前的事件正在处理,但没有及时完成。
因为Android 的是由事件驱动的,looper.loop() 不断地接收事件、处理事件,每一个点击触摸或者说Activity的生命周期都是运行在 Looper.loop() 的控制之下,如果它停止了,应用也就停止了。只能是某一个消息或者说对消息的处理阻塞了 Looper.loop(),而不是 Looper.loop() 阻塞它。
也就说我们的代码其实就是在这个循环里面去执行的,当然不会阻塞了。
Q12:Socket编程步骤
Socket编程步骤分为:服务器端(ServerSocket)和客户端(Socket)
服务器端Socket:ServerSocket
1 在服务器端建立一个ServerSocket绑定相应的端口号,并且在指定的端口进行侦听,等待客户端连接。ServerSocket serverSocket = new ServerSocket(9090);
2 客户端创建连接Socket,并且向服务器端发送请求。
3 服务器收到请求,并且接受客户端的请求信息。调用accept方法等待客户连接。accept方法是一个阻塞的方法,一旦由客户请求,它就会返回一个新的Socket对象用于同客户进行交互。
4 客户端与服务器端通过相应的输入/输出流进行数据的交换。
5 当客户端和服务器端通信完毕后,需要分别关闭socket。
服务器端:
1.创建ServerSocket对象,绑定监听端口
2.通过accept()方法监听客户端请求
3.连接建立后,通过输入流读取客户端发送的请求信息
4.通过输出流向客户端发送响应信息
5.关闭相关资源
客户端:
1.创建Socket对象,指明需要连接的服务器的地址和端口号
2.连接建立后,通过输出流向服务器端发送请求信息
3.通过输入流获取服务器响应的信息
4.关闭相关资源
Q13:java垃圾回收机制
在Java中,如果不再有引用指向对象,这样的对象将不可到达(unreachable)。垃圾回收用于释放不可到达对象所占据的内存。这是垃圾回收的基本原则。
怎么判断一个对象是否需要回收?
- 引用计数(最简单古老的方法):指将资源(可以是对象、内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的过程。缺点:无法检测出循环引用
- 跟踪收集器。对象引用遍历(现在大多数 jvm 使用的方法):对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。
垃圾收集算法: - 标记清除算法:遍历对象图并且记录可到达的对象,以便删除不可到达的对象,一般使用单线程工作并且可能产生内存碎片。
- 标记-压缩回收法:前期与第一种方法相同,只是多了一步,将所有的存活对象压缩到内存的一端,这样内存碎片就可以合成一大块可再利用的内存区域,提高了内存利用率。
- 复制回收法:把现有内存空间分成两部分,gc运行时,它把可到达对象复制到另一半空间,再清空正在使用的空间的全部对象。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。
- 分代回收法:把内存空间分为两个或者多个域,如年轻代和老年代,年轻代的特点是对象会很快被回收,因此在年轻代使用效率比较高的算法。当一个对象经过几次回收后依然存活,对象就会被放入称为老年的内存空间,老年代则采取标记-压缩算法。
Q14:IntentService使用步骤
1 创建一个类继承IntentService类,并重写onHandleIntent()方法,需要在AndroidManifest.xml中使用标签注册该类。
2 发送工作任务到IntentService,通过Intent对象显示指定该类,调用startService方法完成。
3将后台任务执行结果回传给Activity或Fragment,通过LocalBroadcastManager.sendBroadcast()来发送广播。
原理和实例代码详见:
http://blog.csdn.net/lmj623565791/article/details/47143563
Q15:ListView滑动卡顿和解决方法
1 ListView对应的适配器,使用ViewHolder机制,重用contentView,避免每次调用getView方法都创建contentView。
2不要在getView方法中执行耗时操作。
3 控制异步任务的执行频率。
4 如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列表底部的时候再去加载接下来的20条。
5 在列表滑动的时候停止加载图片,尽管这个过程是异步的,等列表停下来以后再加载图。
Q16:接口和抽象类的区别
1一个类只能继承单个类,但是可以实现多个接口。
2接口强调特定功能的实现,而抽象类强调所属关系。
3抽象类中的所有方法并不一定要是抽象的,你可以选择在抽象类中实现一些基本的方法。而接口要求所有的方法都必须是抽象的。
4 抽象类是abstract class修饰,接口是interface修饰。
5抽象类可以有任意类型的属性,接口只能有静态常量修饰的属性。
6 抽象类可以有普通方法和抽象方法,接口的方法都是抽象方法。
7 抽象类和接口都不能实例化,但是抽象类由构造方法,接口没有构造方法。
Q19:ListView滑动卡顿和解决方案
1 ListView对应的适配器,使用ViewHolder机制,重用contentView,避免每次调用getView方法都创建contentView。
2不要在getView方法中执行耗时操作。
3 控制异步任务的执行频率。
4 如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列表底部的时候再去加载接下来的20条。
5在列表滑动的时候停止加载图片,尽管这个过程是异步的,等列表停下来以后再加载图片。
Q20:解析xml的几种方式的原理和特点:DOM,SAX,PULL
DOM:消耗内存,先把xml文档都都读到内存中,然后再用DOM API来访问树形结构,并获取数据。这个写起来很简单,但是很消耗内存。
SAX:解析效率高,占用内存少,基于事件驱动的。更加简单的说就是对文档进行顺序扫描,当扫描到文档开始与结束,元素开始与结束,文档结束等地方时通知事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
PULL:与SAX类似,也是基于事件驱动,我们可以调用它的next方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度块,简单易用,非常适合在android移动设备中使用,android系统内部在解析各种xml时也是用PULL解析器。
Q21:java内部类和内部类分类
java类中方法间定义的类称为java的内部类,可以访问其外部类的私有变量和方法。
分类
- 成员内部类
- 局部内部类
- 匿名内部类
- 静态内部类(定义在类中,任何方法外,用static修饰)
静态内部类
生成一个静态内部类不需要外部类成员。这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:Outer.Inner in=new Outer.Inner();而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。可以定义私有静态内部类。
静态内部类和非静态内部类的区别: - 非静态内部类中不可以声明静态成员变量和静态成员方法。
- 一般非静态内部类可以随意访问其外部类的成员变量以及方法(包括声明为private的方法);静态内部类只能访问其外部类的静态成员变量和静态成员方法,不能访问非静态成员变量和方法。
- 在一个类中创建非静态内部类,内部类的实例一定要绑定在外部类的实例中,在一个外部类中定义一个静态的内部类,不需要利用关键字new来创建内部类的实例,也就是说创建静态内部类对象时,不需要其外部类的对象。
Q22 Java中Collection和Collections的区别(面试题)
- java.util.Collection是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set - Collections是一个包装类,它包含各种有关集合操作的静态方法,此类不能实例化。
Q23:android 中进程的优先级
前台进程
可见进程
服务进程
后台进程
空进程
Q24:静态内部类、内部类、匿名内部类、为什么内部类会持有外部类的引用?持有的引用是this|还是其他?
静态内部类是static修改的内部类
内部类:在某个类的内部又定义了一个类,内部类所嵌入的类称为外部类。
匿名内部类使用new生产的内部类
因为内部类的产生依赖于外部类,持有的引用是类名.this
题目来自2016Android某公司面试题
Q25:Service生命周期,Service中可以执行耗时操作吗?
Service有两种启动方式,bindService()和startService()。
call to bindService()
onCreate()->onBind()->Clients are bound to service->onUnbind()->onDestroy()
Service shut down
call to startService()
onCreate()->onStartCommand()->Service running ->->onDestroy()
Service shut down
Service是运行在主线程的后台服务,不可执行耗时操作,否则出现ANR错误。
Q26: SharedPreferences.Editor 的commit和apply区别
参考API描述,可见:
apply()方法没有返回值,commit()方法有返回值
commit()方法当两个Editor同时修改值,最后一个调用的会生效。如果你不关系返回值,并且在主线程中调用,可以考虑使用apply()方法。先写入内存,然后同步写入持久化存储设备,并返回是否写入成功。
apply()方法当两个Editor同时修改值,最后一个调用的会生效,同步提交到内存,异步提交到硬盘。
原理分析可参考:SharedPreferences 的commit和apply分析
Q27:WebView的pauseTimers方法中断了所有js请求,所以此方法需谨慎使用。
Q28:StringBuilder使用注意事项
1、StringBuilder构造方法
public StringBuilder(String str)
str可以为空,但不能为null。构造方法内部调用append方法,将str添加到StringBuilder中
public StringBuilder(int capacity)
capacity是初始容量大小。** 注意**
2、append方法
append方法添加的数据类型比较全,参数可传String,boolean,char,int,long,float,double,char[],StringBuffer,Object obj等等。比如传null,将添加一个"null"字符串。
Q29: h5页面如何获取手机的imei值
android中获取手机Imei值比较简单,可定义一个方法,然后js与java的交互通过js桥接方式,js调用android中获取手机Imei值的方法。
Q30:LayoutInflater inflate参数解析
LayoutInflater类的inflate方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
参数含义:
root参数:布局映射的父视图
attachToRoot参数:
attachToRoot取值true,添加到父布局root作为子View,并返回父布局root
attachToRoot取值false,映射布局文件resource和父布局root没有任何关联,就是将布局文件生成成一个View对象。