1.了解Framwork不仅能帮助我们学习优秀的代码设计,而且也能帮助我们更好的着手去优化性能。 分析IPC源码过程,在进行activity跳转时候,大致流程如下
每次的activity跳转都是一次跨进程通信。在IPC的过程中每次都要经过zygote进行IApplicationThread和IActivityThread的binder通信。 分析源码和内存Profiler,在Profiler分析中,发现有一些LongSparseArray内存资源,大约20M左右。
而结合zygote源码,在zygote的代码中preloadResources()中会进行一些资源的预加载。主要是activity一些主题或者换肤等一些图片或者皮肤资源。
activity需要这些资源进行主题换肤等可以理解。但是service其实是不需要这些资源的。尤其是作为长时间在后台停留和运转的service,优化资源,节约内存更重要。 因此这些资源是可以优化的部分。
这里可以利用反射获取到对应的集合,然后清除对应的内存信息。从而优化内存。 整体优化收益大约20M左右
Class cls = Class.forName("android.content.res.ResourcesImpl");
Field field1 = cls.getDeclaredField("sPreloadedDrawables");
field1.setAccessible(true);
LongSparseArray<Drawable.ConstantState>[] sPreloadedDrawables = (LongSparseArray<Drawable.ConstantState>[]) field1.get(cls);
Log.i("tag5", "sPreloadedDrawables " + sPreloadedDrawables.length);//length=2
LongSparseArray<Drawable.ConstantState> a0 = sPreloadedDrawables[0];
LongSparseArray<Drawable.ConstantState> a1 = sPreloadedDrawables[1];
Log.i("tag5", "a0 " + a0.size());//82
Log.i("tag5", "a1 " + a1.size());//82
a0.clear();
a1.clear();
sPreloadedDrawables[0] = null;
sPreloadedDrawables[1] = null;
Field field2 = cls.getDeclaredField("sPreloadedColorDrawables");
field2.setAccessible(true);
LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables=(LongSparseArray<Drawable.ConstantState>) field2.get(cls);
Log.i("tag5","sPreloadedColorDrawables "+sPreloadedColorDrawables.size());
sPreloadedColorDrawables.clear();