想着应该记下来比较好
1,子线程也可以更新UI
在oncreate和onresume中可以new thread 然后更新UI,这是因为ViewRootImpl在requestLayout的时候会去checkThread,该方法是在onresume中才去调用的,没有检查机制,所以可以去更新
requestLayout里面呢层层追进去可以看到有一个方法叫performTraversals,这个方法就是绘制view的入口,所以view是在onresume里开始绘制的
再看activityThread的handleResumeActivity方法里,可以看到会有activity.onresume,所以这是管理activity生命周期的类,在performTraversals后会初始化ViewRootImpl,所以在onresume里更新子线程也是可以的,因为activity.onresume发生在ViewRootImpl之前
2,java内存堆和栈
堆栈主要用来加载程序的,用于函数的调用,局部变量的分配
堆是用来存储对象和数组的
堆栈有push和pop的操作,一个函数调用了,就会为其分配一个栈帧,ESP 指向当前栈帧的栈顶,EBP指向栈底,EIP是函数方法指针,栈是在编译时就规定了数据区的大小,灵活性小,但是速度快,仅次于cpu的寄存器,栈中数据共享
除了基本类型(int double float boolean char long byte short)所有对象实例都存放在堆中,数组对象也是,数组名称存在栈中,堆的大小是在运行时动态分配的,不用了就回收了,所以效率低
int a = 3;声明了一个指向int类型的引用a,不是类的引用,称为自动变量,存的是字面值3,追求速度的情况下,是存在栈中的,方法退出后,自动变量也被销毁,a会先去栈中找有没有3的字面值,有就指向他,没有就开辟地址存放3,int b = 3;这个时候指向int类型的引用b会找到有3的值,直接指向这个地址,但是这个和对象引用不一样,不会因为改变了b的值而影响到a的值
integer i = 3 ;虽然没有这种写法,但是可以这样写,内部做了转换Integer i= new Integer(3);
String str = “string”;则不然了,同样,发现没有string字面值则开辟一个地址,然后在栈中这个地址旁边创建了一个string对象o,把这个对象o的字符串指向这个string,返回这个o得地址。
数据包装类的值是不可更改的,不仅仅是String,所有的数据类型的包装类都不可以更改其内部的值
3,进程的创建
app启动:startActivity、startService会用binder方式向sys service发起请求
sys service:调用Process.start 用socket方式向zygote进程发起请求
zygote进程:执行完zygoteInit.main后进入 runselectloop循环中,一旦有客户端请求来了,则调用zygoteConnection.runOnce,层层回调后fork出新的进程
新的进程:回调handleChildeProc后,回调ActivityThread.main方法完成创建
4,复习了一下service的两种绑定方式,以及远程service 和activity绑定,通过binder ,AIDL实现跨进程通信