parent
c70e218458
commit
5a121584e5
@ -0,0 +1,130 @@ |
|||||||
|
--- |
||||||
|
Framework 解决实际问题 |
||||||
|
--- |
||||||
|
|
||||||
|
1. 你有没有解决复杂问题的实践经验 |
||||||
|
2. 你有没有深入研究底层原理的习惯 |
||||||
|
3. 你的知识体系是否有一定深度 |
||||||
|
|
||||||
|
#### 应用组件 |
||||||
|
|
||||||
|
1. 想了解一下为什么 Activity 在 onResume 之后才会显示出来 |
||||||
|
2. bindService 的时候 onRebind 总是调不到,研究原理 |
||||||
|
3. 广播 onReceiver 的 context 可否启动 Activity,显示 Dialog? |
||||||
|
4. 发现 provider 的 onCreate 比 Application 还早,研究一下 |
||||||
|
|
||||||
|
#### 消息通信 |
||||||
|
|
||||||
|
1. intent 带的数据量大了会异常,研究原因 |
||||||
|
2. 需要跨进程传大图,研究 Bitmap 传输原理,Ashmem 机制 |
||||||
|
3. 想知道 Handler 消息延时的精度怎么样,去了解原理 |
||||||
|
4. 为什么有时候 IdleHandler 调不到,去了解原理 |
||||||
|
|
||||||
|
#### 性能优化 |
||||||
|
|
||||||
|
1. ANR 了,看主线程有没有耗时任务 |
||||||
|
2. 卡断掉帧,了解屏幕刷新机制 |
||||||
|
3. 启动速度优化,了解应用启动原理 |
||||||
|
4. 内存优化,清理不必要的资源 |
||||||
|
|
||||||
|
```java |
||||||
|
public class Resources{ |
||||||
|
private static final LongSparseArray<ConstantState>[] sPreloadedDrawables; |
||||||
|
private static final LongSparseArray<ConstantState> sPreloadedColorDrawableds = new LongSparseArray<>(); |
||||||
|
private static final LongSparseArray<ConstantState<ColorStateList>> sPreloadedColorStateLists = new LongSparseArray<>(); |
||||||
|
} |
||||||
|
public static void main(String argvp[]){ |
||||||
|
registerZygoteSocket(socketName); |
||||||
|
preload(); |
||||||
|
if(startSystemServer){ |
||||||
|
startSystemServer(abiList, socketName); |
||||||
|
} |
||||||
|
runSelectLoop(abiList); |
||||||
|
closeServerSocket(); |
||||||
|
} |
||||||
|
static void preload(){ |
||||||
|
preloadClasses(); |
||||||
|
preloadResources(); |
||||||
|
preloadOpenGL(); |
||||||
|
preloadSharedLibraries(); |
||||||
|
preloadTextResources(); |
||||||
|
WebViewFactory.prepareWebViewInZygote(); |
||||||
|
} |
||||||
|
private static void preloadResources(){ |
||||||
|
mResources.startPreloading(); |
||||||
|
if(PRELOAD_RESOURCES){ |
||||||
|
preloadDrawables(runtime, ar); |
||||||
|
preloadColorStateLists(runtime, ar); |
||||||
|
} |
||||||
|
mResources.finishPreloading(); |
||||||
|
} |
||||||
|
private static int preloadDrawables(VMRuntime runtime, TypedArray ar){ |
||||||
|
int N = ar.length(); |
||||||
|
for(int i=0;i<N;i++){ |
||||||
|
int id = ar.getResourceId(i, 0); |
||||||
|
mResources.getDrawable(id, null); |
||||||
|
} |
||||||
|
return N; |
||||||
|
} |
||||||
|
Drawable getDrawable(){ |
||||||
|
final Drawable res = loadDrawable(value, id, theme); |
||||||
|
} |
||||||
|
Drawable loadDrawable(TypeValue value, int id, Theme theme){ |
||||||
|
Drawable dr; |
||||||
|
if(isColorDrawable){ |
||||||
|
dr = new ColorDrawable(value.data); |
||||||
|
}else{ |
||||||
|
dr = loadDrawableForCookie(value, id, null); |
||||||
|
} |
||||||
|
cacheDrawable(value, ... caches, theme, ..., dr); |
||||||
|
return dr; |
||||||
|
} |
||||||
|
private void cacheDrawable(..., long key, Drawable dr){ |
||||||
|
if(isColorDrawable){ |
||||||
|
sPreloadedColorDrawables.put(key, cs); |
||||||
|
}else{ |
||||||
|
if((changingConfigs&LAYOUT_DIR_CONFIG)==0){ |
||||||
|
sPreloadedDrawables[0].put(key, cs); |
||||||
|
sPreloadedDrawables[1].put(key, cs); |
||||||
|
}else{ |
||||||
|
sPreloadedDrawables[mConfiguration.getLayoutDirection()].put(key, cs); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Drawable loadDrawable(TypeValue value, int fd, Theme theme){ |
||||||
|
final Drawable cachedDrawable = caches.getInsstance(key, theme); |
||||||
|
if(cachedDrawable!=null){ |
||||||
|
return cachedDrawable; |
||||||
|
} |
||||||
|
cs = sPreloadedDrawables[mConfiguration.getLayoutDirection()].get(key); |
||||||
|
if(cs!=null){ |
||||||
|
dr = cs.newDrawable(this); |
||||||
|
}else{ |
||||||
|
dr = loadDrawableForCookie(value, id, null); |
||||||
|
} |
||||||
|
cacheDrawable(value, isColorDrawable, caches, theme, ...); |
||||||
|
return dr; |
||||||
|
} |
||||||
|
void cacheDrawable(..., DrawableCache caches, ..., long key, Drawable dr){ |
||||||
|
final ConstantState cs = dr.getConstantState(); |
||||||
|
synchronized(mAccessLock){ |
||||||
|
caches.put(key, cs,); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
总结 |
||||||
|
|
||||||
|
1. zygote 启动的时候会预加载系统资源 |
||||||
|
2. zygote 启动应用进程,应用进程继承了这些系统资源 |
||||||
|
3. 应用 getDrawable 先检查自己的 cache,在检查预加载资源 |
||||||
|
4. 加载完 drawable 后缓存到自己的 cache |
||||||
|
|
||||||
|
解决方案: |
||||||
|
|
||||||
|
1. 可以考虑清理这些预加载资源 |
||||||
|
2. 可以通过反射获取这些资源缓存,然后清理掉 |
||||||
|
3. 适用于不需要 UI 的单独进程的后台 Service |
||||||
|
4. 带 UI 的进程最好还是别随便清 |
||||||
|
|
Loading…
Reference in new issue