
布局优化
- 使用 RelativeLayout, ConstraintLayout 减少布局层级;
- 使用
<include> 标签复用布局;
- 使用
<merge> 标签减少布局嵌套层级;
<merge> 标签经典使用场景:
- (1) 布局顶节点是 FrameLayout ,且不需要设置 background 或 padding 等属性,可以使用
<merge> 代替,因为 Activity 视图的 parent view 就是个 FrameLayout, 所以可以用 merge 消除一个 FrameLayout 节点。
- (2) 某布局作为子布局被其他布局 include 时, 使用
<merge> 标签作为该布局的顶节点,这样在被引入时,顶节点会自动被忽略,而将其子节点全部合并到主布局中。
- 使用
<ViewStub> 标签延迟加载,减少渲染元素;
<ViewStub> 和 View.GONE 的区别是: View.GONE 虽然隐藏不可见了,但是在加载它所在的布局时,就已 经添加到布局上了,而 ViewStub 只会在显示的时候才会渲染布局。
- 移除控件不必要的 background,避免过度绘制;
渲染优化
- 使用 clipRect() 减少自定义 View 过度绘制
- 避免在 onDraw() 方法中创建对象
内存优化
- Bitmap 尺寸压缩 (BitmapOptions.inSampleSize = 2)
- Bitmap 质量压缩 (RGB_565 代替 ARGB_8888, BitmapOptions.inPreferredConfig = RGB_565)
- Bitmap 内存复用 (BitmapOptions.inBitmap = originBitmap)
- 大图局部加载 BitmapRegionDecoder
- Handler 静态内部类 + 弱引用, 单例持 ApplicationContext,BroadcastReceiver 注销,cursor 关闭,Bitmap对象及时 recycle(), 避免内存泄漏
启动优化
- 避免在 Application 的 onCreate 执行耗时操作,使用 IntentService 异步初始化第三方 SDK
- Splash 页面设置 windowBackground 属性,避免启动出现黑白屏
- SplashFragment 实现主页预加载 : 把 SplashActivity 改成 SplashFragment , 应用程序入口仍然是 MainActivity , 在MainActivity 中先展示 SplashFragment, 当 SplashFragment 显示完毕后再将它 remove 掉,同时在 SplashFragment 的 2s 倒计时时间内进行主页数据的网络请求,在 SplashFragment 显示完毕后,再显示出 activity_main 中主界面的布局,主界面布局可能比较复杂,为减少解析时间,可以采用 ViewStub 的形式进行懒加载。
public class MainActivity extends AppCompatActivity {
private MainPageHandler mainPageHandler = new MainPageHandler();
private SplashHideRunnable splashHideRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SplashFragment splashFragment = SplashFragment.newInstance();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.fl_splash, splashFragment);
transaction.commit();
ViewStub viewStub = findViewById(R.id.main_view_stub);
View mainView = viewStub.inflate();
splashHideRunnable = new SplashHideRunnable(this, splashFragment);
getWindow().getDecorView().postDelayed(new Runnable() {
@Override
public void run() {
mainPageHandler.post(splashHideRunnable);
}
}, 2000);
}
private static class SplashHideRunnable implements Runnable {
private WeakReference<AppCompatActivity> appCompatActivityWeakReference;
private WeakReference<SplashFragment> splashFragmentWeakReference;
SplashHideRunnable(AppCompatActivity appCompatActivity, SplashFragment splashFragment) {
this.appCompatActivityWeakReference = new WeakReference<>(appCompatActivity);
this.splashFragmentWeakReference = new WeakReference<>(splashFragment);
}
@Override
public void run() {
SplashFragment splashFragment = splashFragmentWeakReference.get();
AppCompatActivity activity = appCompatActivityWeakReference.get();
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.remove(splashFragment);
ft.commit();
}
}
static class MainPageHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mainPageHandler != null) {
mainPageHandler.removeCallbacks(splashHideRunnable);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ViewStub
android:id="@+id/main_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/activity_main_layout" />
<FrameLayout
android:id="@+id/fl_splash"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
APK 包体积优化
- Lint 工具扫描工程资源,移除未使用的资源。
- gradle 启动代码压缩混淆。
- png 图片压缩。
- 图片资源考虑使用 webP 格式。
- 使用 Shape 代码代替资源图片。
- 移除未使用的资源 resconfig "zh" , "zh_CN","en"
- lib 下考虑只支持主流架构的 so ,移除不需支持的 mips, x86 类型
线程优化
- 使用线程池,复用线程对象,避免频繁创建和销毁线程带来的性能消耗。同时线程池能够有效的控制线程的最大并发数,避免了线程因抢占系统资源从而导致阻塞现象。




