Android优化方案

来源:互联网 发布:90后初中听的网络歌曲 编辑:程序博客网 时间:2024/05/21 17:56

一,图片优化

1,图片加载的框架有,UniversalImageLoader,Picasso,Glide,Fresco。

UniversalImageLoader:本人开发最早使用的框架是UniversalImageLoader,然而这个框架已经过时。虽然这个框架对于内存占用做了一些处理,但是并非完全满足我们的需求,对于加载大图长图图片过多的情况下还是很占内存。并且这个框架配置比较繁琐。之前在平板上做过一个页面,这个页面需要显示大图,图片铺满整个屏幕,平板屏幕本来就很大,在加上图片还很多,用此框架自测很容易发生内存溢出,随便一点内存就能过100MB。

Picasso:这里不再过多介绍。

Glide:Glide是基于Picasso开发的一个框架,也是Google 推荐的一个框架。并且它支持gif动图,包也很小,使用起来很方便。不过这里要注意,这里的gif动图支持并不是非常好。如果你需要展示的动图比较多,并且动图还很大,那么建议用Fresco。本人就遇到过这样扯淡的需求,在平板上显示动图,图片大而且还多,整个页面都是动图。

Fresco:这个框架是Facebook出的,这个框架的出色之处可以适配低端手机。它的缓存策略另辟蹊径,没有在 Java 层处理,直接在更底层的 Native 堆做手脚。于是 Fresco 将图片放到一个特别的内存区域叫 Ashmem 区,就是属于 Native 堆,图片将不再占用 App 的内存,Java 层对此无能为力,这里是属于 C++ 的地盘,所以能大大的减少 OOM。但是Fresco库比较大,支持的多,会使我们app包增加1MB多。还有一个问题需要注意,有一种低端机,如果使用了Fresco框架,并且你的应用是系统应用,那么会导致图片加载不出来。解决方法就是单独把Fresco相关so文件拷贝到系统目录下。

二,过度绘制优化

1,过度绘制就是屏幕上的某个像素在同一帧的时间内被多次绘制。在什么情况下会出现过度绘制?。如果你在xml中使用了多层嵌套的布局,有些布局是不需要显示的,那么这样就会导致过度绘制。过度绘制会浪费大量cpu资源。

2,主要优化点

①,在开发中尽量不要使用多层嵌套的布局,尽量去掉没用的背景色和背景图。

 getWindow().setBackgroundDrawable(null);<style name="AppTheme" parent="android:Theme.Light.NoTitleBar">    <item name="android:windowBackground">@null</item></style>

②,如果你使用了自定义控件,使用Canvas的clipRect和clipPath方法限制View的绘制区域

③,重叠view
使用ViewStub来加载一些不常用的布局,它是一个轻量级且默认不可见的视图,可以动态的加载一个布局,只有你用到这个重叠着的view的时候才加载,推迟加载的时间。

④,尽量使用LinearLayout和RelativeLayout,在层级相同的情况下,尽量用LinearLayout替代RelativeLayout

⑤,使用include把可复用布局单独拿出来

三,数据库优化

1,这里介绍几个数据库框架

①,greenDao:GreenDao是为Android设计的对象关系映射(ORM)工具。它提供了对象到关系型数据库SQLite的相应接口。为了在Android工程中使用greenDao,需要创建另一个“生成器”工程,它的任务是在你的工程域里生成具体的代码。因此相比与其它ORM框架具有出众性能。

②,LitePal:LitePal是对象关系映射(ORM)模型。它使开发者使用SQLite数据库变得非常容易。 你可以不用写一句SQL语句就可以完成大部分数据库操作,包括创建表,更新表,约束操作,聚合功能等等。

③,ORMLite:(Object Relational Mapping Lite)提供了一些轻量级持久化Java对象到SQL数据库,同时也避免了复杂性和更多的标准的ORM包的开销功能。它支持的SQL数据库使用JDBC的数量,还支持原生的Android操作系统数据库API调用sqlite。

④,xutils:xutils中不单是数据库框架,是一个集成框架,其中包含数据库模块

2,这里无论使用哪种框架,对于我们应用本身来说都是好的。我们只需要注意数据库的操作是耗时的,应该放在子线程中去执行。

四,内存泄漏优化

内存泄漏我们通常会考虑到图片加载,然而图片加载只是一部分。开发者过程中比如以下场景

1,静态变量导致的内存泄漏,mContext为静态变量,会导致activity无法正常销毁。

public class MainActivity extends AppCompatActivity {    private static Context mContext;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mContext=this;    }}

2,单例模式导致的内存泄漏

//单例类public class TestManager {    private List<OnDataArrivedListener> mOnDataArrivedListeners = new ArrayList<>();    private static class SingletonHolder {        public static final TestManager testManager = new TestManager();    }    public static TestManager getInstance() {        return SingletonHolder.testManager;    }    public synchronized void registerListener(OnDataArrivedListener listener) {        if (!mOnDataArrivedListeners.contains(listener)) {            mOnDataArrivedListeners.add(listener);        }    }    public synchronized void unRegisterListener(OnDataArrivedListener listener) {        mOnDataArrivedListeners.remove(listener);    }    public interface OnDataArrivedListener {        public void onDataArrived(Object data);    }} //在activity中调用 protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mContext=this;        TestManager.getInstance().registerListener(this);    }

让activity实现OnDataArrivedListener接口注册监听,因为TestManager是单例的,所持有的生命周期长,导致activity对象无法及时释放。

3,属性动画导致的内存泄漏

我们在项目中如果使用了动画,特别是一些无限循环的动画,一定要在acitivty的onDestroy方法中及时结束动画。

4,小结

  • 避免创建过多的对象
  • 不要过多的使用枚举,枚举占用的空间要比整数大
  • 常量使用 static final 来修饰
  • 使用一些Android特有的数据结构,如 SparesArray和Pair等。
  • 适当使用软引用和弱引用
  • 采用内存缓存和磁盘缓存
  • 尽量采用静态内部类,这样可以避免潜在得到由于内部类而导致的内存泄漏
原创粉丝点击