Java基础
public synchronized void run() {
System.out.println(1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(2);
}
复制代码
Demo demo = new Demo();
new Thread(() -> demo.run()).start();
Demo demo2 = new Demo();
new Thread(() -> demo2.run()).start();
复制代码
结果为: 1 1 2 2java
不一样步。但若是使用同一对象访问,结果才是同步的node
Demo demo = new Demo();
new Thread(() -> demo.run()).start();
new Thread(() -> demo.run()).start();
复制代码
输出结果:1 2 1 2android
final关键字用于基本数据类型前:这时代表该关键字修饰的变量是一个常量,在定义后该变量的值就不能被修改。
final关键字用于方法声明前:这时意味着该方法时最终方法,只能被调用,不能被覆盖,可是能够被重载。
final关键字用于类名前:此时该类被称为最终类,该类不能被其余类继承。算法
用try{ }catch(){} 捕获异常时,不管室友有异常,finally代码块中代码都会执行。sql
finalize方法来自于java.lang.Object,用于回收资源。 能够为任何一个类添加finalize方法。finalize方法将在垃圾回收器清除对象以前调用数据库
if(JVM内存不足) {
// 将软引用中的对象引用置为null
str = null;
// 通知垃圾回收器进行回收
System.gc();
}
复制代码
还在用Synchronized?Atomic你了解不?apache
多线程并发问题编程
try{
new Thread(){
public void run(){
if (...) throw new RuntimeException();
}
}.start();
}catch(Exception e){
}
复制代码
答案不能。设计模式
因此线程方法的异常只能本身来处理,线程的问题应该线程本身自己来解决,而不要委托到外部数组
Android基础知识
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));
}
复制代码
为了解决多个线程访问同一个数据问题,同步锁的思路是线程不能同时访问一片内存区域.而ThreadLocal的思路是,干脆给每一个线程Copy一份一摸同样的对象,线程之间各自玩本身的,互相不影响对方 常见ThreadLocal应用场景:确保在每个线程中只有一个Looper的实例对象
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
复制代码
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的成员变量)
Activity对事件响应不超过5秒,BroadcastReceiver执行不超过10秒,Service耗时操做为20秒。不然系统会报ANR
FragmentPageAdapter在每次切换页面的的时候,没有彻底销毁Fragment,适用于固定的,少许的Fragment状况。默认notifyDataSetChanged()刷新是无效的
FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适合页面较多的Fragment使用,这样就不会消耗更多的内存
事务是由一个或多个sql语句组成的一个总体,若是全部语句执行成功那么修改将会所有生效,若是一条sql语句将销量+1,下一条再+1,假若第二条失败,那么销量将撤销第一条sql语句的+1操做,只有在该事务中全部的语句都执行成功才会将修改加入数据库中
sqlite数据库相关操做,主要包括建立和增删改查,事务
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 {
useLibrary 'org.apache.http.legacy'
}
复制代码
Android框架知识
经过注解处理器动态生成java文件,在java文件中进行findViewById和setOnClickListener操做
经过观察者设计模式,先经过注册的方式将指定的类加到一个表里面,等发送消息时轮训那个表,依据注解和注解的value找到匹配的方法,而后执行该方法
LiveData通知其余组件原理主要是观察者设计模式。其优势有
简单来讲,就是可让你本身的类拥有像 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());
复制代码
这样咱们的MyObserver就会感知 activity 的生命周期了
Flowable
和Observable
RxJava1中使用Observable
和Observer
创建起订阅关系,但会产生背压问题。Rxjava2使用Flowable
和Subscriber
替换RaJava1的Observable
和Observer
。Flowable
是在Observable
的基础上优化后的产物,Observable
能解决的问题Flowable
也都能解决。可是并不表明Flowable
能够彻底取代Observable
,Flowable
运行效率要比Observable
慢得多。 只有在须要处理背压问题时,才须要使用Flowable
Rxjava容易遭层内存泄漏。在订阅了事件后没有及时取阅,致使在activity或者fragment销毁后仍然占用着内存,没法释放。而disposable,能够用来取消订阅
参考Rxjava关于Disposable你应该知道的事
设计模式
1.MVC
Android传统就是用MVC模式,Modle(逻辑)和V(View)直接交互,耦合度过高,MVC中是容许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。还有一点就是Presenter与View之间的交互是经过接口的
2.MVP
当View 须要更新数据时,首先去找 Presenter,而后 Presenter 去找 Model 请求数据,Model 获取到数据以后通知 Presenter,Presenter 再通知 View 更新数据,这样 Model 和 View就不会直接交互了,全部的交互都由 Presenter 进行,Presenter 充当了桥梁的角色。很显然,Presenter 必须同时持有 View 和 Model 的对象的引用,才能在它们之间进行通讯
解决办法:
在Presenter中使用弱引用,将view的引用加到弱引用中去 每一个Activity都有BaseActivity,BaseActivity中
3.MVVM
经过双向绑定的机制
算法
Node node4 = new Node(4, null);
Node node3 = new Node(3, node4);
Node node2 = new Node(2, node3);
Node node1 = new Node(1, node2);
Node pHead = node1;//头结点
复制代码
这组链表从1到4排序,要求反转后4到1
public static Node reverseList(Node pHead) {
Node pReversedHead = null; //反转事后的单链表存储头结点
Node pNode = pHead; //当前节点
Node pPrev = null; //前一结点
while (pNode != null) {
//1.记录next,下一步:更新当前节点的上一节点和自己。最后移动一位
Node pNext = pNode.next;
if (pNext == null) {
//到了尾节点
pReversedHead = pNode;
}
pNode.next = pPrev;
pPrev = pNode;
pNode = pNext;
}
return pReversedHead;
}
复制代码
输出
pHead = reverseList(pHead);//反转以后头结点
while (pHead != null) {
System.out.println(pHead.key);
pHead = pHead.next;
}
复制代码