WindowManagerService
//Activity
final void attach{
mWindow = new PhoneWindow(this, window, activityConfigCallback);
//viewrootimpl 里点击回调的地方
mWindow.setCallback(this);
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
}
//window
public void setWindowManager{
//mWindowManager = WindowManagerImpl
// WindowManagerImpl 类似contextwrapper 的装饰者模式,他里面主要是一个 mGlobal
也就是 WindowManagerGlobal 来执行真正的操作
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
@Override
public void setContentView(int layoutResID) {
//初始化DecorView
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
//ActivityThread
public void handleResumeActivity {
//这才真的吧view添加进window
//WindowManagerImpl -> WindowManagerGlobal .addView()
wm.addView(decor, l);
}
//WindowManagerGlobal
//viewrootimpl 和decorview进行绑定
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
ViewRootImpl root;
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mParams.add(wparams);
root.setView(view, wparams, panelParentView);
//viewrootimpl
public void setView{
requestLayout();
}
@Override
public void requestLayout() {
//检查线程
checkThread();
scheduleTraversals();
}
//编舞者监听 ,会通过handler接到异步消息,但这也是为什么onResume拿不到宽高
//因为在doTraversal 计算宽高,doTraversal 不在super.onResume里执行,而是后面回调回来的
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
//同步屏障
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
}
}
// performMeasure performLayout performDraw
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
SurfaceFlinger
整合各个surface数据,共同发给硬件
Surface
用来记录界面 的位置,大小颜色
SurfaceView, TextureView区别
TextureView
需要硬件加速
和个普通view一样,可以旋转动画
延迟比较高
SurfaceView
有自己独立windowstate 和layer
Surface
持有一个canvas
viewrootimpl 里canvas = mSurface.lockCanvas(dirty); 拿到canvas
同时 Surface.lockCanvas() 建立与sufaceFlinger的联系
先onResume 再onStop的流程
//ActivityThread
public void handleResumeActivity{
//最后一步,这个用来调用之前activity STOP
Looper.myQueue().addIdleHandler(new Idler());
}
//Idler
public final boolean queueIdle() {
//activityManagerService
am.activityIdle(a.token, a.createdConfig, stopProfiling);
}
//ActivityManagerService
public final void activityIdle{
ActivityRecord r =
mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
false /* processPausingActivities */, config);
}
// ActivityStackSupervisor
final ActivityRecord activityIdleInternalLocked{
stack.stopActivityLocked(r);
}
// ActivityStack
final void stopActivityLocked{
//这里又回调回applicationThread啦,注意用的StopActivityItem,执行他的excute时
mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
StopActivityItem.obtain(r.visible, r.configChangeFlags));
}
//StopActivityItem
//ClientTransactionHandler 就是ActivityThread
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions,
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
class 怎么判断相同
1, 类名+ 包名 相同
2,加载的 classLoader是同一个
classLoader
baseDexClassLoader -> DexPathList 包含
//我们新的dex 就可以放这里面
private Element[] dexElements;
//so 加载路径
NativeLibraryElement[] nativeLibraryPathElements;
网络优化
1,httpdns
2, 合并网络请求
3,keep-alive,多路复用
4, gizp压缩
5,Protocol Buffer
6,缓存
apk瘦身
1,图标
2,混淆
3,andGuard 修改resources.arsc
4,插件化(有版本维护问题,支付宝都改为网页了)
大图加载
先通过看要差多大,比如现在只有内存只有10K,我们要加载10m的
那就是inSampleSize = n. 缩小的 倍数 n^2 > 10m/10. n ^2 >= 1024
即n = 10 ,n会向下取2的整数次方,最后效果可能只有8,因此要判断如果不是i = log2 不是整数,不是就n = 2^(i%1+1)
//拿到剩下内存
Runtime.getRuntime().freeMemory();
BitmapFactory.Options options = new BitmapFactory.Options();
//只计算大小
options.inJustDecodeBounds = true;
//宽高都是1/3 总的是1/9 ,但是错了,inSampleSize 注释里写的是
//any other value will be rounded down to the nearest power of 2.
//也就是如果inSampleSize 会向下取2^n次方,比如你写3,应该就是2,你写10就是8
options.inSampleSize = 3;
Bitmap bitmap = BitmapFactory.decodeFile("xxx.png");
//压缩图片 去磁盘
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
jvm 方法区会oom嘛
参考链接
会的,比如加载了过多类,过多方法
1.6 永久代,字符串常量池 ,静态变量,常量,运行时常量池,类,方法,jit等信息
1.7 没有永久代,字符串常量池 ,静态变量移动到堆了
1.8 改为元空间
localSocket和socket区别
localSocket主要用于进程间通信,减少不必要的网络协议栈
如何寻找anr问题
anr /data/anr/trace.txt 里 tid =1的线程的日志栈
偏向锁 升级轻量级要stw,轻升重呢
轻升重不需要,偏向锁其实就是没锁,当他修改markdown信息为轻量锁的时候,担心别人也在用,所以要stw,但是轻升重,轻已经加锁了,所以不需要
app启动安全模式
检查是否启动 crash设置个flag = 上次的 flag+1(本地持久化)
1,如果app10秒以后退出,清空
2,如果用户手动到后台,清空
3, 正常生命流程退出,清空
通过flag进行级别判断
flag
or
清除全部数据
判断有热修复配置,先进行热修复
binder
1,bindService会回调回主线程
2,bindService 最大线程数15
3,超过最大线程数会等待
静态内部类单例模式
jvm类用到才会加载,没用到不会加载,因此有延迟加载的作用
返回什么
public int tryFinallyReturn() {
try {
throw new Exception("return");
} catch (Exception e) {
return 0;
} finally {
return 1;
}
}
返回1,因为try catch 和finlly的关系就是无论怎么样都会执行finally,如果t-c 过程中遇到return就先执行finlly,如果finally有return, 就不会执行t-c里的return了,毕竟能暂停return只有finally
zygote为什么不使用binder
愿意很简单,因为binder是多线程的,而fork不支持多线程,容易造成死锁等问题
zygote为什么不使用binder
okhttp 对一域名 最多几个链接
5个
android屏幕刷新机制