Android代码优化

Android代码优化工具 1.前言:在我们平时项目开发中,经常会写一些不严谨的代码或者一些比较低级的错误代码,但是这些错误往往很难被发现,这样就导致了我们的项目中会隐藏了很多影响性能甚至是导致闪退的错误代码,于是许多响应的检测工具就出现了.在这里我就介绍一下我比较常用的几个检测工具吧项目DEMO源码2.FindBugs顾名思义,FindBugs是一个寻找bug的工具,更具体的说FindBugs是一个静态检测java代码的工具 阅读详情

Android官方建议,编写高效的代码的准则如下:

  • 不要做冗余的工作
  • 进来避免次数过多的分配内存
  • 其实还需要再添加一条准则:深入理解所用语言特性和系统平台的API,具体到Android开发,熟练掌握Java语言,并对Android SDK所提供的API了如指掌。

数据结构的选择

正确的选择数据结构很重要,对Java中常见的数据结构例如ArrayList和LinkedList,HashMap和HashSet等,需要做到对他们的联系和区别有比较深入的了解,方便再编码的时候做出正确的选择,下面我们再Android开发中使用SparseArray代替HashMap为例进行说明。SparseArray是Android平台特有的稀疏数组的实现,它是Integer到Object的一个映射,再特定场合可用于替代HashMap<Integer,<E>>,提高性能。他的核心是现实二分查找算法。

//This is Arrays.binarySearch(), but dosen't do any argument validation.
static int binarySearch(int[] array, int size, int value){
    int lo = 0;
    int hi = size - 1;
    while(lo <= hi){
            final int mid = ( lo + hi) >>> 1;
            final int midVal= array[mid];
            if(midVal < value){
                lo = mid + 1;
            }else if(midVal > value){
                hi = mid - 1;
            }else{
                return mid;    // value found
            }
        }
        return ~lo;    //value not present
}

SparseArray家族目前有下面的四大类

//用于替代HashMap<Integer, Boolean> booleanMap = new HashMap<Integer, Boolean>();
SparseBooleanArray booleanArray = new SparseBooleanArray();

//用于替代HashMap<Integer, Integer> booleanMap = new HashMap<Integer, Integer>();
SparseIntArray intArray = new SparseIntArray();

//用于替代HashMap<Integer, Long> booleanMap = new HashMap<Integer, Long>();
SparseLongArray longArray = new SparseLongArray();

//用于替代HashMap<Integer, String> booleanMap = new HashMap<Integer, String>();
SparseArray<String> stringArray = new SparseArray<String>();

需要注意的几点如下:

SparseArray不是线程安全的

由于要进行二分查找,因此,SparseArray会对插入的数据按照Key值大小顺序插入。

SparseArray对删除操作做了优化,它并不会立即删除这个元素,而是通过设置标识位(DELETED)的方式,后面尝试重用。

再Android工程中运行Lint进行静态代码分析,会有一个名为AndroidLintUseSparseArrays的检查项,如果违规,它会提示

HashMap can be replaced with SparseArray

这样可以很轻松的找到工程可优化的地方。


Handler和内部类的正确用法

Android代码中设计线程通信的地方通常会使用Handler,典型的代码结构如下。

public class HandlerActivity extends Activity{
	
	//可能引入泄露的方法
	private final Handler mLeakyHandler = new Handler(){
		
		@Override
		public void handleMessage(Message msg){
			// ....
		}
	};

}

使用Android Lint分析这段代码,会违反检查项AndroidLintHandlerLeak,得到如下提示。

This Handler calss should be static or leaks might occour

那么产生内存泄漏的原因可能是什么呢?我们知道Handler是和Looper以及MessageQueue一起工作的,再Android中,一个应用启动以后,系统默认会创建一个为主线程服务的Looper对象,该Looper对象用于处理主线程的所有Message对象,它的生命周期贯穿于整个应用的生命周期。在主线程中使用的Handler都会默认绑定到这个Looper对象。在主线程中创建Handler对象时,它会立即关联主线程Looper对象的MessageQueue,这时发送到MessageQueue中的Message对象都会持有这个Handler对象的引用,这样在Looper处理消息时才能回调到Handler的handleMessage方法。因此,如果Message还没有被处理完成,那么Handler对象也就不会被垃圾回收。

在上面的代码中,将Handler的实例声明为HandlerActivity类的内部类。在Java语言中,非静态内部匿名类会持有外部类的一个隐式的引用,这样就可能会导致外部类无法被垃圾回收。因此,最终由于MessageQueue中的Message还没有处理完成,就会持有Handler对象的引用,而非静态Handler对象会持有外部类HandlerActivity的引用,这个Activity无法被垃圾回收从而导致内存泄漏。

一个明显会引入内存泄漏的例子

public class HandlerActivity extends Activity{

	//可能引入泄露的方法
	private final Handler mLeakyHandler = new Handler(){
	
		@Override
		public void handleMessage(Message msg){
		
			//.....
		
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		
		//延迟5分钟发送消息
		mLeakyHandler.postDelayed(new Runnable(){
		
			@Override
			public void run(){
				//......
			}
			
		}, 1000*60*5);
		
	
	}
}

由于消息延迟5分子发送,因此,当用户进入这个Activity并退出以后,在消息发送并处理完成之前,这个Activity是不会被系统回收的(系统内存确实不够的情况例外)

解决方案如下:

  • 在子线程中使用Handler,这时需要开发者自己创建一个Looper对象,这个Looper对象的生命周期同一般的Java对象,因此这种方法可行
  • 将Handler声明为静态的内部类,前面说过,静态内部类不会持有外部类的引用,因此,也不会引起内存泄漏。经典用法的代码如下
public class HandlerActivity extends Activity{

	/*
	声明一个静态的Handler内部类,并持有外部类的弱引用
	*/
	private static class InnerHandler extends Handler{
		
		private final WeakReference<HandlerActivity> mActivity;
		
		public InnerHandler(HandlerActivity activity){
			mActivity = new WeakReference<HandlerActivity>(activity);
		}
		
		@Override
		public void handleMessage(Message msg){
			HandlerActivity activity = mActivity.get();
			if(activity != null){
				//.....
			}
		}
	}
	
	private final InnerHandler mHandler = new InnerHandler(this);
	
	/*
	静态匿名内部类不会持有外部类的引用
	*/
	private static final Runnable sRunnable = new Runnable(){
	
		@Override
		public void run(){
			//......
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		
		//延迟5分子发送消息
		mHandler.postDelayed(sRunnable, 1000*60*5);
	}
	
}

正确的使用Context

Context应该是每个入门Android的程序员第一个接触的概念,他代表当前上下文的环境,可以用来实现很多功能的调用,语句如下

/获取资源管理器对象,进而可以访问到例如String,color等资源
Resources resources = context.getResources();

//启动指定的Activity
context.startActivity(new Intent(this, MainActivity.class));

//获取各种系统服务
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

//获取系统文件目录
File internalDir = context.getCacheDir();
File externalDir = context.getExternalCacheDir();

//更多...

可见,正确的理解Context的概念是很重要的,虽然在应用开发中随处可见Context的使用,但并不是所有的Context实力都具有相同的功能,在使用上需要区别对待,否则会很容易引入问题。总结下面的Context的种类

Context的种类

根据Context依托的组件以及用途的不同,我们可以将Context分为如下几种。

  • Application:Android应用中的默认单例类,在Activity或者Service中通过getApplication()可以获取到这个单例,通过context.getApplicationContext()可以获取到应用全局唯一的Context实例。
  • Activity/Service:这两个类都是ContextWrapper的子类,在这两个类中可以通过getBaseContext()获取到他们的Context实例,不同的Activity或者Service实例,他们的Context都是独立的,不会复用。
  • BroadcastReceiver:和Activity以及Service不同,BroadcastReceiver本身并不是Context的子类,而是在回调函数onReceive()中由Android框架传入一个Context实例。系统传入的这个Context实例都是经过功能裁剪的,他不能调用registerReceiver()以及bindService()这两个函数。
  • ContentProvider:同样的,ContentProvider也不是context的子类,但是在创建时系统会传入一个Context实例,这样在ContentProvider中可以通过调用getContext()函数获取。如果ContentProvider和调用者处于相同的应用进程中,那么getContext()将返回应用全局唯一的Context实例。如果是其他进程调用的ContentProvider,那么ContentProvider将持有自身所在进程的Context实例。

错误使用Context导致的内存泄漏

错误的使用Context可能会导致内存泄漏,典型的例子是在实现单例模式时使用Context,如下代码是可能会导致内存泄漏的单利实现。

public class SingleInstance{

	private static SingleInstance sInstance;
	
	private SingleInstance(Context context){
		mContext = context;
	}
	
	public static SingleInstance getInstance(Context context){
	
		if(sInstance == null){
			sInstance = new SingleInstance(context);
		}
		
		return sInstance;
		
	}
}

如果使用者调用getInstance时传入的Context是一个Activity或者是Service实例,那么在应用退出之前,由于单利模式一直存在,会导致对应的Activity或者Service被单利引用,从而不会被垃圾回收,Acitivty或者Service中关联其他View或者数据结构对象也不会被释放,从而导致内存泄漏。正确的做法是使用ApplicationContext,因为它是应用唯一的,而生命周期和应用一致的,正确的单例实现如下。

public class SingleInstance{
	
	private Context mContext;
	private static SingleInstance sInstance;
	
	private SingleInstance(Context context){
		mContext = context;
	}
	
	public static SingleInstance getInstance(Context context){
		if(sInstance == null){
		
			//获取到上下文对象
			sInstance = new SingleInstance(context.getApplicationContext());
			
		}
		return sInstance;
	}
}

不同的Context对比

不同组件中的Context能提供的功能不尽相同,总结如下

功能ApplicationActivityServiceBroadcastReceiverContentProvider
显示DialogNOYESNONONO
启动ActivityNO[1]YESNO[1]NO[1]NO[1]
实现layout InflationNO[2]YESNO[2]NO[2]NO[2]
启动ServiceYESYESYESYESYES
绑定ServiceYESYESYESYESNO
发送BroadcastYESYESYESYESYES
注册BroadcastYESYESYESYESNO[3]
加载资源ResourceYESYESYESYESYES
  • 其中NO[1]表示对应的组建并不是真的启动Activity,而是建议不要这么做,因为这些组件会在新的Task中创建Activity,而不是在原来的Task中。
  • NO[2]标记也是表示也不建议这么做,因为在非Activity中进行Layout Inflation,会使用系统默认的主题,而不是应用中设置的主题。
  • NO[3]标记表示在Android4.2及以上的系统上,如果注册的BroadcastReceiver是null时是可以的,用来获取sticky广播的当前值。

掌握Java的四种引用方式

掌握Java的四种引用类型对于写出内存使用良好的应用是很关键的

  • 强引用(StrongReference):强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
  • 软引用(SoftReference):如果一个对象只具有软引用,当内存空间足够时,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
  • 弱引用(WeakReference):从名字可以看出,弱引用势必软引用更弱的一种引用类型,只有弱引用指向对象的生命周期更短。当垃圾回收器扫描到只有弱引用的对象时,不论当前的内存空间是否不足,都会对弱引用对象进行回收。弱引用也可以和一个引用队列配合使用,当弱引用指向的对象被回收以后,Java虚拟机会将这个弱引用加入到与之关联的引用队列中。
  • 虚引用(PhantomReference)"虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是 否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

特别注意,在程序设计中一般很少使用弱引用与虚引用,使用软引用的情况较多,这是因为软引用可以加速JVM对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生。


其他代码微优化

避免创建非必要的对象

对象的创建需要内存分配,对象的销毁需要垃圾回收,这些都会在一定程度上影响应用的性能。因此一般来说,最好是重用对象而不是在每次需要的时候去创建一个功能相同的新对象,特别是注意不要在循环中重复创建相同的对象。

1. 简介

一般来说,我们最好的做法是重用对象,而不是每次使用都new出一个新的相同功能的对象,这样做很高效,特别是对于那些不可变类来说。

2. 例子

引用书中的一个很好的例子:比如有一个Person对象,对象中有一个字段是生日,生日是个常量,它不能被更改,现在需要完成一个方法,用这个方法我们可以获取到这个人是否出生在1946到1964年之间(也就是生育高峰期(baby boomer)),你会怎么做呢?
像下面这样?:

public class Person {
        private final Date birthday;
        public Person(Date birthday) {
            this.birthday = birthday;
        }

        public boolean isBabyBoomer() {
            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            c.set(1946, Calendar.JANUARY, 1, 0, 0, 0);//将时间设置为1946年1月1日0时0分0秒
            Date boomStart = c.getTime();
            c.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
            Date boomEnd = c.getTime();
            return birthday.compareTo(boomStart) >= 0 && 
                              birthday.compareTo(boomEnd) < 0;
        }
}

isBabyBoomer在每次调用的时候都会创建一个Calendar 一个TimeZone和两个Date实例,这些都是不必要的,下面是改进版本:

public class Person {
        private final Date birthday;

        private static final Date BOOM_START;
        private static final Date BOOM_END;

        public Person(Date birthday) {
            this.birthday = birthday;
        }

        static {
            Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            c.set(1946, Calendar.JANUARY, 1, 0, 0, 0);//将时间设置为1946年1月1日0时0分0秒
            BOOM_START = c.getTime();
            c.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
            BOOM_END = c.getTime();
        }

        public boolean isBabyBoomer() {
            return birthday.compareTo(BOOM_START) >= 0 && 
                          birthday.compareTo(BOOM_END) < 0;
        }
}

3. 如果想要保证性能,则请尽量使用基本数据类型。

每次自动装箱(autoboxing)都会穿件一个多余的对象,比如:

Integer value = 0;

上面这段代码就是自动装箱,每次这样做都会穿件一个多余的Integer对象。

总结

本条的重点是避免创建多余的对象,提高重用性,但是需要注意对象的重用不能是盲目的,对于对象的重用,我们应该把目光集中在那些重量级的类,或是构造方法中需要做很多初始化的类的身上。对于一些比较轻量级的类,我们应该将代码的简洁和可维护性放在跟高的优先级上。


对常量使用static final修饰

对于基本数据类型和String类型的变量,建议使用static final修饰,因为final类型的常量会在会进入静态dex文件的与初始化部分,这是对基本数据类型和String类型常量的调用不会涉及类的初始化,而是直接调用字面量。

不要将视图控件声明为static,因为View对象会引用Activity对象,当Activity退出时其对象本身无法被销毁,会造成内存溢出


避免内部的Getters/Setters

在面向对象编程中,Getters/Setters的作用主要是对外屏蔽具体的变量定义,从而达到更好封装性。而如果是在类内部还是用Getters/Setters函数访问变量的话,会降低访问的速度。根据Android官方文档,在没有JIT(Just In Time)编译器时,直接访问变量的速度是调用Getter方法的3倍;在JIT编译时,直接访问变量的速度是调用Getter方法的7倍。当然,如果你的应用中使用了ProGuard的话,那么ProGuard会对Getters/Setters进行内联擦做,从而达到直接访问的效果。


数据类型的选择

字符串拼接用StringBuilder代替String,在非并发情况下用StringBuilder代替StringBuffer,如果你对字符串的长度有大致了解,如100字符左右,可以直接new StringBuilder(128)指定初始大小,减少空间不够时的再次分配。64位类型如long double的处理比32位如int慢,final类型存储在常量区中读取效率更高


数据结构选择
常见的数据结构选择如:
ArrayList和LinkedList 

  • ArrayList根据index取值更快,LinkedList更占内存、随机插入删除更快速、扩容效率更高。一般推荐ArrayList。

ArrayList、HashMap、LinkedHashMap、HashSet 

  • hash系列数据结构查询速度更优,ArrayList存储有序元素,HashMap为键值对数据结构,LinkedHashMap可以记住加入次序的hashMap,HashSet不允许重复元素。

HashMap、WeakHashMap 

  • WeakHashMap中元素可在适当时候被系统垃圾回收器自动回收,所以适合在内存紧张型中使用。

Collections.synchronizedMap和ConcurrentHashMap 

  • ConcurrentHashMap为细分锁,锁粒度更小,并发性能更优。Collections.synchronizedMap为对象锁,自己添加函数进行锁控制更方便。

Android也提供了一些性能更优的数据类型,如SparseArray、SparseBooleanArray、SparseIntArray、Pair 
Sparse系列的数据结构是为key为int情况的特殊处理,采用二分查找及简单的数组存储,加上不需要泛型转换的开销,相对Map来说性能更优


代码的重构

代码重构是一项持之以恒的工作,需要依靠团队中每一个成员来维护代码库的高质量,如何有效的进行代码重构,推荐阅读《重构-改善既有的代码设计》和《代码整洁之道》

总结:

  • 了解编程语言的编译原理,使用高效编码方式从语法上提高程序性能
  • 采用合理的数据结构和算法提高程序性能,决定程序性能的关键
  • 采用多线程、缓存数据、延迟加载、提前加载等手段,解决严重的性能瓶颈
  • 合理配置虚拟机堆内存使用上限和使用率,减少垃圾回收频率
  • 合理使用native代码
  • 合理配置数据库缓存类型和优化SQL语句加快读取速度,使用事务加快写入速度
  • 使用工具分析性能问题,找出性能瓶颈

参考文章:

https://www.jianshu.com/p/2e699709aa79

https://www.aliyun.com/jiaocheng/32118.html

移动开发中的 Android Jetpack 代码优化策略 本文旨在为Android开发者提供一套完整的Jetpack代码优化策略,帮助开发者理解Jetpack组件的工作原理,并掌握在实际项目中进行性能优化的具体方法。我们将重点讨论Jetpack架构组件、数据库访问、后台任务处理等核心模块的优化技巧。文章首先介绍Jetpack的核心概念,然后深入分析各组件优化策略,接着通过实际案例展示优化方法,最后讨论实际应用场景和未来发展趋势。Jetpack: Google提供的一套库、工具和指南集合,帮助开发者遵循最佳实践,减少样板代码ViewModel。 阅读详情

相关推荐

给汽车芯片做‘体检’:手把手教你用IEC62380和SN29500估算功能安全失效率

本文详细介绍了如何使用IEC62380和SN29500标准估算汽车芯片的功能安全失效率,涵盖基础认知、方法论对比及实战计算。通过具体案例演示两种标准的应用流程,帮助工程师准确评估半导体器件的可靠性,确保符合ISO 26262标准要求。

weixin_28725553的博客 458

Android性能优化:SparseArray

当我们在使用HashMap的时候,会弹出提示:use SparseArray<E> instead of for better performance 和HashMap的不同点还是挺多的,不过大部分资料都从网上可以查到,可以参考Android编程之SparseArray详解 我这里主要是想自己记录一下要点 采用二分法查找算法,因为SparseArray存储数值的方法是按照key值大小排列 有

moon-sky的专栏 642

RK3588-NANOPC-T6移植ubuntu+xenomai内核

更具网址下载相应的内核。导入到开发板并执行内核。

qq_42007446的博客 573

一些提高Android开发效率的工具&方法

一些提高开发效率的工具&方法 1. 使用快捷键提高操作效率 下面的有些快捷键是经过我修改的,如果你不知道AS原生的快捷键是什么或者忘记了快捷键可以到Settings->Keymap下面搜索查看,使用熟练了之后就会记住了。当然你也可以在Settings->Keymap中修改自己觉得顺手的快捷键组合。 快捷键 作用 对应菜单路径 Ctrl + F 当前文件查找内容 ...

川峰的博客 3567

IDM更改下载路径的详细指南

Internet Download Manager(IDM)是一款功能全面的下载加速工具,它支持多种浏览器和协议,能够显著提升下载速度,同时提供断点续传、多线程下载等实用功能。IDM的用户界面简洁明了,操作便捷,使得用户能够轻松管理下载任务。此外,IDM还支持自动分类下载文件、定时下载等高级功能,进一步提升了用户的下载体验。通过本文的介绍,相信用户已经掌握了如何在IDM中更改下载路径的方法。这一功能不仅提升了下载效率和文件管理便捷性,还满足了用户的个性化需求。

nntxthml的博客 1763

Python爬虫实战:Boss直聘职位数据采集实战 - Playwright + 结构化解析完整方案(附CSV导出 + SQLite持久化存储)!

我长期专注 Python 爬虫工程化实战,主理专栏 《Python爬虫实战》:从采集策略到反爬对抗,从数据清洗到分布式调度,持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”,让数据价值真正做到——抓得到、洗得净、用得上。

喵手的博客 2188

android开发该如何提高Android程序的效率

安卓开发中的安卓程序效率很重要,如果你做出一款登录很慢,打开很延时的产品,相信很多人都不愿意去使用,那 么如何提高Android程序效率呢,也就是如何来优化Android的性能呢?本文提供给你一些想法,希望能够给广大安卓 开发者带来灵感: 1)首先要有良好的编码习惯 一个优秀的开发者应该善于运用常识、完善的算法和标准设计模式。要有资源意识,打开了就要记得关闭

彦过留痕--的专栏 629

OpenClaw第2章:快速安装

本章将手把手教你安装 OpenClaw。

Maynor的博客 3236

Lint工具使用说明

Lint工具使用说明     Android-Lint是SDK Tools16 (ADT 16)之后才引入的工具,通过代码检查,可发现潜在的问题,并能对Android程序进行优化处理。在AndroidStudio中已经集成了该工具,下面直接演示使用方法。        1)首先单击菜单栏中的“Analyse”——>选择“Inspect Code”然后Android Studio会弹出“Spec

知识改变命运~ 2756

AI赋能数字人:打造与语音节奏完美匹配的高质量手势动画

想象一个场景:当你与一位数字人交谈时,它不仅能理解你的言语,还能恰到好处地挥动手臂、比划手势,就像真实的人类交流一样自然流畅。这正是当前AI技术致力于实现的目标——通过分析语音内容,自动生成与之相匹配的手势动作,为数字人赋予更加丰富的情感表达和非言语沟通能力。AI手势生成技术的出现,标志着数字人在模仿人类自然交流方式上迈出了重要一步。随着技术的不断成熟与应用场景的拓宽,未来我们可以期待更多富有表现力和情感互动的数字人出现在我们的日常生活中,开启人机交互的新篇章。

这里汇聚了前沿的技术分享与实用的开发技巧,带你探索从创意到企业的技术创业之路。 793

【WorkBuddy专栏40】从「帮你干活」到「帮你创造」——WorkBuddy设计创意功能深度拆解

【WorkBuddy专栏40】从「帮你干活」到「帮你创造」——WorkBuddy设计创意功能深度拆解

AI人人懂 1299

如何在Android开发中让你的代码更有效率,耗时两个礼拜8000字Android面试长文

这个图片app的代码:https://github.com/penkzhou/iogallery。ppt:http://greenrobot.qiniudn.com/103.pdf。 现在我将视频里面的内容记录如下: 使用LruCache避免OOM 首先我们的图片app是用来展示手机里面保存的图片。当app里面需要展示大量的图片的时候,我们需要将这些图片从disk加载到内存当中。如果我们来回地滑动activity,系统会重复许多disk I/O;而且在一个activity里面同时加载多张图片将会占用大量内

wqwq_22的博客 256

时间序列—显著相关性和滞后性分析_python

本文讲述了两个时间序列(信号)的相关性分析,可以利用相关性分析进行特征筛选。此外本文还讲了怎么判断时间序列的滞后性的方法。

qq_34229228的博客 2万+

android代码优化

通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻辑,但是性能不一定是最优化的。一般来说,优秀的程序员在写完代码之后都会不断的对代码进行重构。重构的好处有很多,其中一点,就是对代码进行优化,提高软件的性能。下面我们就从几个方面来了解Android开发过程中的代码优化。 1)静态变量引起内存泄露 在代码优化的过程中,我们需要对代码中的静态变量特别留意。静态变量

认真做事,开心生活 776

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Android平台上进行代码优化

合理安排UI更新,利用`Handler`、`Choreographer`或者`RecyclerView`的动画机制,避免过于频繁地刷新界面。- 适当使用弱引用、软引用以及生命周期感知组件,如`LiveData`和`ViewModel`,以适应组件生命周期的变化。- 控制内存分配,特别是在循环中避免创建大量临时对象,考虑使用局部变量、数组缓冲区等手段。- 优化算法,减少不必要的计算和循环,尤其是对于大量数据或频繁执行的操作。- 使用索引、合理设计表结构,并优化SQL查询语句,减少数据库查询时间。

weixin_34991050的博客 409

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android优化浅谈之Java代码优化

Android优化包括许多方面,就从Java代码优化、内存泄露、UI优化等几个方面来介绍一下。今天主要介绍一下Java代码优化。   Java代码优化:Java代码优化主要是要一些Java的编程技巧和优化原则。 1、尽量使用static和final修饰符:使用static修饰符可以调高调用的效率且减少空间占用。final变量的值不可被修改、不可被覆盖、不可派生,适当地使用final不仅可以保护

潘洪金的博客 1217

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

android 代码优化

Android代码优化的核心原则:不做不必要的事,不分配不必要的内存 1、字符串频繁操作时,多用StringBuffer而少用String 2、尽量使用本地变量,即反复使用的变量要先保存成临时或局部变量,尤其是循环中使用的变量 3、String方法中substring和indexOf都是native方法可以大量的使用 4、如果函数返回String类型,而且返回后的使用就是要加入到Strin

shenyuemei的专栏 643

Android代码优化工具——Android lint

作为移动应用开发者,我们总希望发布的APK文件越小越好,不希望没有用到的图片资源也被打包进去,不希望应用中使用了高于minSdk的API,也不希望Manifest文件存在异常,lint就能解决我们的这些问题。Android lint是在ADT 16提供的新工具,它是一个代码扫描工具,能够帮助我们识别代码结构存在的问题,主要包括: 布局性能(以前是layoutopt工具,可以解决无用布局、嵌套

choubaoguai的专栏 581

Android中的代码优化

Android代码优化的核心原则:不做不必要的事,不分配不必要的内存 1、字符串频繁操作时,多用StringBuffer而少用String 2、尽量使用本地变量,即反复使用的变量要先保存成临时或局部变量,尤其是循环中使用的变量 3、String方法中substring和indexOf都是native方法可以大量的使用 4、如果函数返回String类型,而且返回后的使用就是要加入到Str

zhengzhihao1的专栏 769

安卓代码优化

 我们的目标是写出更加高效的代码。根据Android官方的建议,编写高效代码的两个基本准则如下:.不要做冗余的工作。.尽量避免次数过多的内存分配操作。其实还要加上第三个准则:深入的理解所用语言特性和系统平台的API,具体到Android开发,就是要熟练掌握Java语言,并对Android SDK 所提供的API了如指掌。1.数据结构的选择2.Handler和内部类的正确用法3.正确的使用Conte...

Q 的博客 2612

Android-一些关于代码优化的事儿

Android-一些关于代码优化的事儿 内容来自这里:http://www.madhome.org/read.php?tid=1769 直接引用了,唉,看来有不少细节要注意。 简介 对于占用资源的系统,有两条基本原则:不要做不必要的事 不要分配不必要的内存 所有下面的内容都遵照这两个原则。 有些人可能马上会跳出来,把本节的大部分内容归于“草率的优化”(参见[The Root of

阿赞的专栏 468
上一篇: JVM类加载机制
下一篇: Android性能优化之图片优化
augfun
博客等级 码龄10年 311粉丝 662原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值