3.final 、finally、finalize 区别
- final关键字用于基本数据类型前:这时表明该关键字修饰的变量是一个常量,在定义后该变量的值就不能被修改。
final关键字用于方法声明前:这时意味着该方法时最终方法,只能被调用,不能被覆盖,但是可以被重载。
final关键字用于类名前:此时该类被称为最终类,该类不能被其他类继承。
- 用try{
}catch(){} 捕获异常时,无论室友有异常,finally代码块中代码都会执行。
- finalize方法来自于java.lang.Object,用于回收资源。
可以为任何一个类添加finalize方法。finalize方法将在垃圾回收器清除对象之前调用
4. Java中成静态内部类和非静态内部类特点
-
静态内部类:和外部类没有什么”强依赖”上的关系,耦合程度不高,可以单独创建实例。由于静态内部类与外部类并不会保存相互之间的引用,因此在一定程度上,还会节省那么一点内存资源
-
内部类中需要访问有关外部类的所有属性及方法
5.强引用、弱引用、软引用和虚引用
-
强引用:当内存空间不足时,Java虚拟机宁愿抛出OutOfMemoryError错误也不会回收,直接new出来的就是强引用
-
软引用:内存空间充足时,垃圾回收器不会回收它;如果内存空间不足了,就会回收这些对象的内存。
当内存不足时,JVM首先将软引用中的对象引用置为null,然后通知垃圾回收器进行回收
if(JVM内存不足) {
// 将软引用中的对象引用置为null
str = null;
// 通知垃圾回收器进行回收
System.gc();
}
-
弱引用:在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象
-
虚引用:虚引用顾名思义,就是形同虚设。与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收
6.原子变量Atomic
7.多线程并发问题
Android基础知识
1.Looper总结
- Looper通过prepare方法进行实例化,先从他的成员变量sThreadLocal中拿取,没有的话就new 一个Looper,然后放到sThreadLocal中缓存。每个线程只能创建一个Looper实例
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException(“Only one Looper may be created per thread”);
}
sThreadLocal.set(new Looper(quitAllowed));
}
-
Looper通过loop方法开启循环队列,里面开启了死循环,没有msg时候会阻塞
-
在ActivityThread的main方法中也就是Activity启动的时候,已经调用了Looper.prepareMainLopper()方法
2.ThreadLocal在Looper中的使用
为了解决多个线程访问同一个数据问题,同步锁的思路是线程不能同时访问一片内存区域.而ThreadLocal的思路是,干脆给每个线程Copy一份一摸一样的对象,线程之间各自玩自己的,互相不影响对方
常见ThreadLocal应用场景:确保在每一个线程中只有一个Looper的实例对象
- ThreadLocal的set方法
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
- ThreadLocal的get方法
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings(“unchecked”)
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
简而言之:先拿到当前线程,再从当前线程中拿到ThreadLocalMap,通过ThreadLocalMap来存储数据。(ThreadLocalMap是Thread的成员变量)
3.Service 和 IntentService
Activity对事件响应不超过5秒,BroadcastReceiver执行不超过10秒,Service耗时操作为20秒。否则系统会报ANR
-
使用startService()方法启用服务后,调用者与服务之间没有关连。调用者直接退出而没有调用stopService的话,Service会一直在后台运行
-
使用bindService()方法启用服务,调用者与服务绑定在一起了,调用者一旦退出,服务也就自动终止
-
IntentService是Service的子类,会创建子线程来处理所有的Intent请求,其onHandleIntent()方法实现的代码,无需处理多线程问题
4.FragmentPageAdapter和FragmentPageStateAdapter的区别
-
FragmentPageAdapter在每次切换页面的的时候,没有完全销毁Fragment,适用于固定的,少量的Fragment情况。默认notifyDataSetChanged()刷新是无效的
-
FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适合页面较多的Fragment使用,这样就不会消耗更多的内存
5.Sqlite数据库,什么是事务
事务是由一个或多个sql语句组成的一个整体,如果所有语句执行成功那么修改将会全部生效,如果一条sql语句将销量+1,下一条再+1,倘若第二条失败,那么销量将撤销第一条sql语句的+1操作,只有在该事务中所有的语句都执行成功才会将修改加入数据库中
6.怎么做Sqlite数据库升级
-
直接删除老数据库,但会造成数据丢失,一般不采用
-
对数据库进行升级,参考SQLite数据库版本升级
7.invalidate与requestLayout区别
-
vi
ew调用invalidate将导致当前view的重绘,viewGroup调用invalidate会使viewGroup的子view调用draw -
requestLayout方法只会导致当前view的measure和layout,而draw不一定被执行。只有当view的位置发生改变才会执行draw方法
8.View和ViewGroup区别
-
ViewGroup
的onInterceptTouchEvent
默认返回false,即不拦截事件,View
没有拦截事件方法,View
默认时消耗事件的 -
ViewGroup
默认不会调用onDraw方法,View
默认会调用onDraw方法。可以通过setWillNotDraw(boolean willNotDraw)
来指定是否调用onDraw方法
/**
-
If this view doesn’t do any drawing on its own, set this flag to
-
allow further optimizations. By default, this flag is not set on
-
View, but could be set on some View subclasses such as ViewGroup.
-
Typically, if you override {@link #onDraw(android.graphics.Canvas)}
-
you should clear this flag.
-
@param willNotDraw whether or not this View draw on its own
*/
public void setWillNotDraw(boolean willNotDraw) {
setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
}
Android框架知识
1.buttnife实现原理
通过注解处理器动态生成java文件,在java文件中进行findViewById和setOnClickListener操作
2. EventBus实现原理
通过观察者设计模式,先通过注册的方式将指定的类加到一个表里面,等发送消息时轮训那个表,依据注解和注解的value找到匹配的方法,然后执行该方法
3.LiveData原理
LiveData通知其他组件原理主要是观察者设计模式。其优点有
-
遵从应用程序的生命周期,如在Activity中如果数据更新了但Activity已经是destroy状态,LivaeData就不会通知Activity(observer)
-
不会造成内存泄漏
4.Lifecycle
简单来说,就是可以让你自己的类拥有像 activity 或 fragment 一样生命周期的功能。继承Lifecycle 的组件将生命周期脱离出 activity 而转到自己身上
使用步骤:
(1) 继承DefaultLifecycleObserver
class TestObserver implements DefaultLifecycleObserver {
@Override
public void onCreate(LifecycleOwner owner) {
// your code
}
}
(2) LifecycleOwner是只有一个方法getLifecycle()的接口,是让拥有生命周期的东西实现比如(activity)用来获取Lifecycle。在Android Support Library 26.1.0 及其之后已经activity 和 fragment 已经默认实现了LifecycleOwner
所以在 activity 里我们可以直接:
getLifecycle().addObserver(new MyObserver());
implements DefaultLifecycleObserver {
@Override
public void onCreate(LifecycleOwner owner) {
// your code
}
}
(2) LifecycleOwner是只有一个方法getLifecycle()的接口,是让拥有生命周期的东西实现比如(activity)用来获取Lifecycle。在Android Support Library 26.1.0 及其之后已经activity 和 fragment 已经默认实现了LifecycleOwner
所以在 activity 里我们可以直接:
getLifecycle().addObserver(new MyObserver());