Android APP耗电优化

可能造成耗电的一些原因

  • 网络请求耗电,而且手机数据网络进行http请求比无线网进行http请求更加耗电,因为数据网络调用到一些底层的硬件模块,就如GPS一样,当手机打开GPS功能后,也是启动了一些硬件模块就会明显增加耗电
  • 高频的刷新UI界面,刷新UI界面其实就是进行layout的绘制,如果一个Activity的布局嵌套太多层,那么每一层layout都会刷新一次,例如动画等等这些都会造成耗电
  • 数据库,SD卡文件操作,这些都是属于耗时操作,当操作次数很少的时候基本不会有耗电问题,但是当短时间内操作次数很多的话,也会明显的增加耗电,同时也有可能造成页面卡顿
  • AlarmManager,例如一些推送的心跳包实现,AlarmManager会定时唤醒CPU去执行一些任务,也是造成耗电的一大源头
  • 手机网络环境不好的时候会频繁的切换网络,因为网络数据交互的时候,系统也是会被唤醒的,所以APP如果在监听了网络切换广播后做了大量的操作,一样会增加耗电
  • 针对一些任务队列的处理,如果队列堆积的任务太多,导致循环执行太久也会造成耗电,因为占用了CPU资源去执行代码,我们的log日志工具保存到文件就是用任务队列实现的,当压力测试SDK一次性接受1万条消息的时候,那内存就表上来了,跟了下发现日志保存队列里面积压了4千多个任务,这时候即使手机锁屏,也还会不断的把队列中的任务执行完然后CPU才会休眠下去的,同样会造成严重的耗电,耗内存,好在release版本的日志都是关闭的
  • 执行一些高运算量的代码,例如json数据解析,一些二进制协议的数据编码和解码
  • 接收系统的一分钟广播,然后做一些程序逻辑处理,其实接收一分钟广播不耗电,耗电的是一分钟执行一次程序处理
  • Wake Lock使用不当导致没有及时的释放,Wake Lock可以阻止cpu进入休眠的,如果没有及时的release会造成cpu无法休眠,程序耗电严重
  • 如果程序中有定时任务,在cpu休眠之后,定时任务就会被挂起不执行,这时候并不会造成太大的耗电,但是如果这个定时任务的时间间隔很短,1秒执行一次,那么当手机app集成了推送,推送就会有心跳包通过AlarmManager来唤醒,每次唤醒的时候就会再去执行挂起的定时任务,虽然执行定时任务的耗电量可能比心跳包的耗电量少很多,不过还是需要注意的,积少成多
  • 其实android中的Log日志的打印也会耗电的,在日常开发中,我们可能不仅会把log打印到AndroidStudio里面,有可能还会保存起来,而且可能在打印对象信息数据的时候会用到json格式转换,这些都会增加耗电,但是在正式发布的apk包中日志管理一般都是关闭的
  • 在手机锁屏后,CPU会过一段时间才休眠,如果程序中有定时任务,在CPU休眠后会被挂起不执行,但是在CPU休眠之前,定时任务还是会一直的执行的,之前遇到过这么一个问题,我们采用Picasso库:Picasso.with(context)
Picasso(Context context, Dispatcher dispatcher, Cache cache, Listener listener,RequestTransformer requestTransformer, List<RequestHandler> extraRequestHandlers, Stats stats,Bitmap.Config defaultBitmapConfig, boolean indicatorsEnabled, boolean loggingEnabled) {this.context = context;this.dispatcher = dispatcher;this.cache = cache;this.listener = listener;this.requestTransformer = requestTransformer;this.defaultBitmapConfig = defaultBitmapConfig;int builtInHandlers = 7; // Adjust this as internal handlers are added or removed.int extraCount = (extraRequestHandlers != null ? extraRequestHandlers.size() : 0);List<RequestHandler> allRequestHandlers =new ArrayList<RequestHandler>(builtInHandlers + extraCount);// ResourceRequestHandler needs to be the first in the list to avoid// forcing other RequestHandlers to perform null checks on request.uri// to cover the (request.resourceId != 0) case.allRequestHandlers.add(new ResourceRequestHandler(context));if (extraRequestHandlers != null) {allRequestHandlers.addAll(extraRequestHandlers);}allRequestHandlers.add(new ContactsPhotoRequestHandler(context));allRequestHandlers.add(new MediaStoreRequestHandler(context));allRequestHandlers.add(new ContentStreamRequestHandler(context));allRequestHandlers.add(new AssetRequestHandler(context));allRequestHandlers.add(new FileRequestHandler(context));allRequestHandlers.add(new NetworkRequestHandler(dispatcher.downloader, stats));requestHandlers = Collections.unmodifiableList(allRequestHandlers);this.stats = stats;this.targetToAction = new WeakHashMap<Object, Action>();this.targetToDeferredRequestCreator = new WeakHashMap<ImageView, DeferredRequestCreator>();this.indicatorsEnabled = indicatorsEnabled;this.loggingEnabled = loggingEnabled;this.referenceQueue = new ReferenceQueue<Object>();this.cleanupThread = new CleanupThread(referenceQueue, HANDLER);this.cleanupThread.start();}

在Picasso构造的过程中:启动了一个线程CleanupThread

private static class CleanupThread extends Thread {private final ReferenceQueue<Object> referenceQueue;private final Handler handler;CleanupThread(ReferenceQueue<Object> referenceQueue, Handler handler) {this.referenceQueue = referenceQueue;this.handler = handler;setDaemon(true);setName(THREAD_PREFIX + "refQueue");}@Override public void run() {Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND);while (true) {try {// Prior to Android 5.0, even when there is no local variable, the result from// remove() & obtainMessage() is kept as a stack local variable.// We're forcing this reference to be cleared and replaced by looping every second// when there is nothing to do.// This behavior has been tested and reproduced with heap dumps.RequestWeakReference<?> remove =(RequestWeakReference<?>) referenceQueue.remove(THREAD_LEAK_CLEANING_MS);Message message = handler.obtainMessage();if (remove != null) {message.what = REQUEST_GCED;message.obj = remove.action;handler.sendMessage(message);} else {message.recycle();}} catch (InterruptedException e) {break;} catch (final Exception e) {handler.post(new Runnable() {@Override public void run() {throw new RuntimeException(e);}});break;}}}void shutdown() {interrupt();}}
  • CleanupThread线程里面是有一个while(true){}循环,这个就会在手机锁屏后持续运行一段时间才会被挂起的,这个过程就增加了耗电,然后打开查看CPU使用情况,发现app一直被占用一点点,正常情况下,app的退到后台后,cpu应该是不会一直被占用的,如下图:

 
包名com.xtc.watch在退到后台之后仍然在占用CPU的资源执行一些东西,然后打开AndroidStudio,查看monitor里面的cpu的方法跟踪功能(Start method tracing) 
,红色部分就表示cpu被占用的比例,过一段时间后再次点击Start Method Tracing按钮停止方法跟踪,然后AndroidStudio会自动生成一个后缀名为.trace的分析文件: 

上图中Thread后面的是执行方法所在线程的名称,Wall Clock Time表示程序从运行到终止所花费的时间,Thread Time是线程执行的时长,CPU Time是CPU的运行时间,在Thread列表里面的就表示在方法跟踪期间有执行过的线程,下面有颜色的长条是线程执行的时间信息Wall clock time和cpu time,如果在程序退到后台,手机锁屏后,仍然不断有程序里面的线程在跑,那么就存在了耗电风险了,你想想,程序退到后台,手机锁屏了,这时候所有程序线程有在方法跟踪期间的县城都已经展示出来了,如果发现程序耗电,很可能就是由于线程还在不断的运行造成的 
- 在Service里面执行一些循环代码,也 
可能造成耗电;如果Service是前台Service,那Service的进程优先级会比较高,或者是一些后台常驻Service,在这些Service执行无限循环的代码,耗电耗到手机发烫:

public class PushService extends Service {private static final String tag = PushService.class.getSimpleName();private ExecutorService executorService = Executors.newSingleThreadExecutor();private Queue<Runnable> taskQueue = new LinkedList<>();@Overridepublic void onCreate() {super.onCreate();Log.i(tag, this.getPackageName() + ":" + this.getClass().getSimpleName() + " onCreate.");Runnable task = null;while (!executorService.isShutdown()) {if ((task = taskQueue.poll()) != null) {task.run();}}}@Overridepublic void onDestroy() {super.onDestroy();Log.i(tag, this.getPackageName() + ":" + this.getClass().getSimpleName() + " onDestroy.");executorService.shutdownNow();}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

while循环里面的poll()方法并不是阻阻塞的,因此会一直重复的跑这段代码导致CUP即使在手机锁屏的时候仍然高速的在运行着循环代码

针对以上原因进行相应的优化

  • 针对Http请求:

    1. 对http请求数据做GZIP压缩,当前流行的http第三方看默认都支持GZIP压缩
    2. Http缓存,Http协议有一个Cache机制,当发出http请求的时候会先到指定目录下检查是否已经存在这个请求的数据,如果存在并且还没过时,那么就会直接返回;而一些第三方例如OkHttp也有有自己的缓存机制OKHTTP缓存
    3. 合并Http请求来减少Http请求次数,因为Http底层也是TCP连接,对于每个Http请求,发出请求的时候都会创建TCP连接,请求结束后会断开TCP连接,那么当Http请求次数很多的时候就会频繁的创建和断开TCP连接,如果把当中一些请求进行合理的合并,那么就会减少Http请求次数
    4. 制定合理的Http请求数据格式和返回数据格式,做到请求数据中没有冗余字段
    5. 可以在Http请求数据格式里面加一个字段dataVersion代表本地已有数据的版本号,然后传到服务器,服务器的数据表中也有一个字段是dataVersion,当服务器数据被修改的时候,dataVersion就加一,当检测到客户端传上来的dataVersion小于服务器数据表中的dataVersion的时候就返回最新数据,否则可以直接返回空数据代表当前本地数据已经是最新数据,这样就不会每次请求http的时候都会返回大量数据,当数据没有被改变的时候直接返回空,减少了http请求过程中的数据交互(但是要考虑一点,只有一些请求数据量比较大的才适合,因为增加了dataVersion字段后无论给客户端还是服务端也都相应的增加了维护的成本)
  • 针对数据库,SD卡文件操作: 
    1. APP在对数据库或者SD卡文件操作的时候无非也是涉及到一些数据的转换,json转换,可以采用json解析效率高的第三方库,例如fast json,Jackson,gson
    2. 可以把一些需要持久化到数据库或者文件中的数据先缓存在内存中,然后在一个时间点一起触发一同更新到数据库或者文件中;例如,在进入Activity的时候会首先从数据库中搜索出帐户信息并且展示在界面,然后会再去发Http请求服务器的帐户信息数据,再把服务器最新的帐户信息数据刷新到界面中,同时也存在一个内存对象中,这时候先不更新到数据库,当退出这个Activity界面的时候可以去检测帐户数据是否发生改变,如果改变了就更新到数据中;这么做的好处是:如果在Activity界面多次修改数据,那最新的数据都是只更新到内存中的,当Activity退出后才把最新的帐户信息数据更新到数据库中,没必要更改一次就同时把数据更新一次到数据库
    3. SD卡的文件读写操作比数据库要快,数据库也是属于文件,但是在写数据的时候还要经过sqlite的一些列数据库操作,但是SD卡在写数据的时候是直接写到文件中的,所以针对与简单数据,标志变量或者数据条数很少的数据,而且安全性要求也不高的数据可以直接存在文件中,例如SharedPreferences中,只有关系型的数据,数据安全性较高的,数据记录条数比较多的可以选择数据库存储,而且如果数据库进行加密后,对于数据库的读写操作会更慢了
    4. 针对数据库操作尽量不要直接使用android里面的Sqlite来手写读写的那些sql语句,可以选择一些orm框架库,例如ormlite,GreenDao等等,我们选择的是ormlite,因为ormlite数据库加密已经有现成的库可以提供使用

Android APP耗电优化

2016年10月18日 18:25:47

阅读数:2887

可能造成耗电的一些原因

  • 网络请求耗电,而且手机数据网络进行http请求比无线网进行http请求更加耗电,因为数据网络调用到一些底层的硬件模块,就如GPS一样,当手机打开GPS功能后,也是启动了一些硬件模块就会明显增加耗电
  • 高频的刷新UI界面,刷新UI界面其实就是进行layout的绘制,如果一个Activity的布局嵌套太多层,那么每一层layout都会刷新一次,例如动画等等这些都会造成耗电
  • 数据库,SD卡文件操作,这些都是属于耗时操作,当操作次数很少的时候基本不会有耗电问题,但是当短时间内操作次数很多的话,也会明显的增加耗电,同时也有可能造成页面卡顿
  • AlarmManager,例如一些推送的心跳包实现,AlarmManager会定时唤醒CPU去执行一些任务,也是造成耗电的一大源头
  • 手机网络环境不好的时候会频繁的切换网络,因为网络数据交互的时候,系统也是会被唤醒的,所以APP如果在监听了网络切换广播后做了大量的操作,一样会增加耗电
  • 针对一些任务队列的处理,如果队列堆积的任务太多,导致循环执行太久也会造成耗电,因为占用了CPU资源去执行代码,我们的log日志工具保存到文件就是用任务队列实现的,当压力测试SDK一次性接受1万条消息的时候,那内存就表上来了,跟了下发现日志保存队列里面积压了4千多个任务,这时候即使手机锁屏,也还会不断的把队列中的任务执行完然后CPU才会休眠下去的,同样会造成严重的耗电,耗内存,好在release版本的日志都是关闭的
  • 执行一些高运算量的代码,例如json数据解析,一些二进制协议的数据编码和解码
  • 接收系统的一分钟广播,然后做一些程序逻辑处理,其实接收一分钟广播不耗电,耗电的是一分钟执行一次程序处理
  • Wake Lock使用不当导致没有及时的释放,Wake Lock可以阻止cpu进入休眠的,如果没有及时的release会造成cpu无法休眠,程序耗电严重
  • 如果程序中有定时任务,在cpu休眠之后,定时任务就会被挂起不执行,这时候并不会造成太大的耗电,但是如果这个定时任务的时间间隔很短,1秒执行一次,那么当手机app集成了推送,推送就会有心跳包通过AlarmManager来唤醒,每次唤醒的时候就会再去执行挂起的定时任务,虽然执行定时任务的耗电量可能比心跳包的耗电量少很多,不过还是需要注意的,积少成多
  • 其实android中的Log日志的打印也会耗电的,在日常开发中,我们可能不仅会把log打印到AndroidStudio里面,有可能还会保存起来,而且可能在打印对象信息数据的时候会用到json格式转换,这些都会增加耗电,但是在正式发布的apk包中日志管理一般都是关闭的
  • 在手机锁屏后,CPU会过一段时间才休眠,如果程序中有定时任务,在CPU休眠后会被挂起不执行,但是在CPU休眠之前,定时任务还是会一直的执行的,之前遇到过这么一个问题,我们采用Picasso库:Picasso.with(context)
Picasso(Context context, Dispatcher dispatcher, Cache cache, Listener listener,RequestTransformer requestTransformer, List<RequestHandler> extraRequestHandlers, Stats stats,Bitmap.Config defaultBitmapConfig, boolean indicatorsEnabled, boolean loggingEnabled) {this.context = context;this.dispatcher = dispatcher;this.cache = cache;this.listener = listener;this.requestTransformer = requestTransformer;this.defaultBitmapConfig = defaultBitmapConfig;int builtInHandlers = 7; // Adjust this as internal handlers are added or removed.int extraCount = (extraRequestHandlers != null ? extraRequestHandlers.size() : 0);List<RequestHandler> allRequestHandlers =new ArrayList<RequestHandler>(builtInHandlers + extraCount);// ResourceRequestHandler needs to be the first in the list to avoid// forcing other RequestHandlers to perform null checks on request.uri// to cover the (request.resourceId != 0) case.allRequestHandlers.add(new ResourceRequestHandler(context));if (extraRequestHandlers != null) {allRequestHandlers.addAll(extraRequestHandlers);}allRequestHandlers.add(new ContactsPhotoRequestHandler(context));allRequestHandlers.add(new MediaStoreRequestHandler(context));allRequestHandlers.add(new ContentStreamRequestHandler(context));allRequestHandlers.add(new AssetRequestHandler(context));allRequestHandlers.add(new FileRequestHandler(context));allRequestHandlers.add(new NetworkRequestHandler(dispatcher.downloader, stats));requestHandlers = Collections.unmodifiableList(allRequestHandlers);this.stats = stats;this.targetToAction = new WeakHashMap<Object, Action>();this.targetToDeferredRequestCreator = new WeakHashMap<ImageView, DeferredRequestCreator>();this.indicatorsEnabled = indicatorsEnabled;this.loggingEnabled = loggingEnabled;this.referenceQueue = new ReferenceQueue<Object>();this.cleanupThread = new CleanupThread(referenceQueue, HANDLER);this.cleanupThread.start();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

在Picasso构造的过程中:启动了一个线程CleanupThread

private static class CleanupThread extends Thread {private final ReferenceQueue<Object> referenceQueue;private final Handler handler;CleanupThread(ReferenceQueue<Object> referenceQueue, Handler handler) {this.referenceQueue = referenceQueue;this.handler = handler;setDaemon(true);setName(THREAD_PREFIX + "refQueue");}@Override public void run() {Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND);while (true) {try {// Prior to Android 5.0, even when there is no local variable, the result from// remove() & obtainMessage() is kept as a stack local variable.// We're forcing this reference to be cleared and replaced by looping every second// when there is nothing to do.// This behavior has been tested and reproduced with heap dumps.RequestWeakReference<?> remove =(RequestWeakReference<?>) referenceQueue.remove(THREAD_LEAK_CLEANING_MS);Message message = handler.obtainMessage();if (remove != null) {message.what = REQUEST_GCED;message.obj = remove.action;handler.sendMessage(message);} else {message.recycle();}} catch (InterruptedException e) {break;} catch (final Exception e) {handler.post(new Runnable() {@Override public void run() {throw new RuntimeException(e);}});break;}}}void shutdown() {interrupt();}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

CleanupThread线程里面是有一个while(true){}循环,这个就会在手机锁屏后持续运行一段时间才会被挂起的,这个过程就增加了耗电,然后打开查看CPU使用情况,发现app一直被占用一点点,正常情况下,app的退到后台后,cpu应该是不会一直被占用的,如下图: 
 
包名com.xtc.watch在退到后台之后仍然在占用CPU的资源执行一些东西,然后打开AndroidStudio,查看monitor里面的cpu的方法跟踪功能(Start method tracing) 
,红色部分就表示cpu被占用的比例,过一段时间后再次点击Start Method Tracing按钮停止方法跟踪,然后AndroidStudio会自动生成一个后缀名为.trace的分析文件: 

上图中Thread后面的是执行方法所在线程的名称,Wall Clock Time表示程序从运行到终止所花费的时间,Thread Time是线程执行的时长,CPU Time是CPU的运行时间,在Thread列表里面的就表示在方法跟踪期间有执行过的线程,下面有颜色的长条是线程执行的时间信息Wall clock time和cpu time,如果在程序退到后台,手机锁屏后,仍然不断有程序里面的线程在跑,那么就存在了耗电风险了,你想想,程序退到后台,手机锁屏了,这时候所有程序线程有在方法跟踪期间的县城都已经展示出来了,如果发现程序耗电,很可能就是由于线程还在不断的运行造成的 
- 在Service里面执行一些循环代码,也 
可能造成耗电;如果Service是前台Service,那Service的进程优先级会比较高,或者是一些后台常驻Service,在这些Service执行无限循环的代码,耗电耗到手机发烫:

public class PushService extends Service {private static final String tag = PushService.class.getSimpleName();private ExecutorService executorService = Executors.newSingleThreadExecutor();private Queue<Runnable> taskQueue = new LinkedList<>();@Overridepublic void onCreate() {super.onCreate();Log.i(tag, this.getPackageName() + ":" + this.getClass().getSimpleName() + " onCreate.");Runnable task = null;while (!executorService.isShutdown()) {if ((task = taskQueue.poll()) != null) {task.run();}}}@Overridepublic void onDestroy() {super.onDestroy();Log.i(tag, this.getPackageName() + ":" + this.getClass().getSimpleName() + " onDestroy.");executorService.shutdownNow();}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

while循环里面的poll()方法并不是阻阻塞的,因此会一直重复的跑这段代码导致CUP即使在手机锁屏的时候仍然高速的在运行着循环代码

针对以上原因进行相应的优化

  • 针对Http请求:

    1. 对http请求数据做GZIP压缩,当前流行的http第三方看默认都支持GZIP压缩
    2. Http缓存,Http协议有一个Cache机制,当发出http请求的时候会先到指定目录下检查是否已经存在这个请求的数据,如果存在并且还没过时,那么就会直接返回;而一些第三方例如OkHttp也有有自己的缓存机制OKHTTP缓存
    3. 合并Http请求来减少Http请求次数,因为Http底层也是TCP连接,对于每个Http请求,发出请求的时候都会创建TCP连接,请求结束后会断开TCP连接,那么当Http请求次数很多的时候就会频繁的创建和断开TCP连接,如果把当中一些请求进行合理的合并,那么就会减少Http请求次数
    4. 制定合理的Http请求数据格式和返回数据格式,做到请求数据中没有冗余字段
    5. 可以在Http请求数据格式里面加一个字段dataVersion代表本地已有数据的版本号,然后传到服务器,服务器的数据表中也有一个字段是dataVersion,当服务器数据被修改的时候,dataVersion就加一,当检测到客户端传上来的dataVersion小于服务器数据表中的dataVersion的时候就返回最新数据,否则可以直接返回空数据代表当前本地数据已经是最新数据,这样就不会每次请求http的时候都会返回大量数据,当数据没有被改变的时候直接返回空,减少了http请求过程中的数据交互(但是要考虑一点,只有一些请求数据量比较大的才适合,因为增加了dataVersion字段后无论给客户端还是服务端也都相应的增加了维护的成本)
  • 针对数据库,SD卡文件操作: 
    1. APP在对数据库或者SD卡文件操作的时候无非也是涉及到一些数据的转换,json转换,可以采用json解析效率高的第三方库,例如fast json,Jackson,gson
    2. 可以把一些需要持久化到数据库或者文件中的数据先缓存在内存中,然后在一个时间点一起触发一同更新到数据库或者文件中;例如,在进入Activity的时候会首先从数据库中搜索出帐户信息并且展示在界面,然后会再去发Http请求服务器的帐户信息数据,再把服务器最新的帐户信息数据刷新到界面中,同时也存在一个内存对象中,这时候先不更新到数据库,当退出这个Activity界面的时候可以去检测帐户数据是否发生改变,如果改变了就更新到数据中;这么做的好处是:如果在Activity界面多次修改数据,那最新的数据都是只更新到内存中的,当Activity退出后才把最新的帐户信息数据更新到数据库中,没必要更改一次就同时把数据更新一次到数据库
    3. SD卡的文件读写操作比数据库要快,数据库也是属于文件,但是在写数据的时候还要经过sqlite的一些列数据库操作,但是SD卡在写数据的时候是直接写到文件中的,所以针对与简单数据,标志变量或者数据条数很少的数据,而且安全性要求也不高的数据可以直接存在文件中,例如SharedPreferences中,只有关系型的数据,数据安全性较高的,数据记录条数比较多的可以选择数据库存储,而且如果数据库进行加密后,对于数据库的读写操作会更慢了
    4. 针对数据库操作尽量不要直接使用android里面的Sqlite来手写读写的那些sql语句,可以选择一些orm框架库,例如ormlite,GreenDao等等,我们选择的是ormlite,因为ormlite数据库加密已经有现成的库可以提供使用

Android 系统(102)---Android APP耗电优化相关推荐

  1. 开发一个基于 Android系统车载智能APP

    很久之前就想做一个车载相关的app.需要实现如下功能: (1)每0.2秒更新一次当前车辆的最新速度值. (2)可控制性记录行驶里程. (3)不连接网络情况下获取当前车辆位置.如(北京市X区X路X号) ...

  2. qt android 重启,一种Android系统支持QT APP的实现方法专利_专利查询 - 天眼查

    1.一种Android系统支持QT APP的实现方法,其特征在于:所述实现方法首先使 Ministro服务能作为Android系统的系统应用程序运行,其次将QT程序依赖的QT库以及其 他文件部署到An ...

  3. android 服务端技术,移动应用服务器端开发(基于JSP技术)-2017 Android系统构架 Android系统构架.docx...

    Android系统构架 PAGE 1 目 录 TOC \o "1-3" \h \z \u 一.Android系统构架 1 二.Linux内核层 2 三.系统运行库层 3 (一)系统 ...

  4. android log抓取方法,Android系统之Android抓取各种log的方法

    Android系统之Android抓取各种log的方法 2018年11月25日 | 萬仟网移动技术 | 我要评论 android之android抓取各种log的方法 1.logcat (四类log b ...

  5. Android系统架构-[Android取经之路]

    摘要:本节主要来讲解Android的系统架构 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! 欢 ...

  6. 【android系统】android系统升级流程分析(二)---update升级包分析

    接下来我们将通过几篇文章来分析update.zip包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的工作原理.今天让我先来分析下升级包update.zip. 一 ...

  7. 【android系统】android系统升级流程分析(一)---recovery模式中进行update包升级流程分析

    今天我们直接来看下android中具体的升级过程是如何的. 升级流程概述 升级的流程图: 升级流程分析 第一步:升级包获取 升级获取可以通过远程下载,也可直接拷贝到指定目录即可. 第二步:准备升级 然 ...

  8. android系统裁剪之APP精简

    APP精简的目标是精简手机root下system/app和system/priv-app两个目录里的APK文件. 精简的手段是:弄清这些应用的用处,搞明白这些应用是否对系统无用,有没有用需要根据自己的 ...

  9. android系统视频剪辑app推荐,知乎10w人收藏:玩短视频必装的9款剪辑App(最全)...

    声明:本文来自于微信公众号 微果酱(ID:wjam123456),作者:   橙子,授权站长之家转载发布. 做运营的 每天都要面临一些新难题 比如老板想追潮流做短视频 吐血写脚本.拍完视频 磨刀霍霍向 ...

最新文章

  1. linux内存和缓冲区,linux – 内存消失了(不,不是缓冲区或缓存)
  2. 计算机网络 | IP协议相关技术与网络总结 :DNS、ICMP、DHCP、NAT/NAPT、通信流程
  3. 云优YUNUCMS企业网站管理系统
  4. Python 3 Basics
  5. 防火墙(ASA)高级配置之URL过滤、日志管理、透明模式
  6. opencv怎么2个摄像头_扭到腰该怎么办?5个处理要点要谨记,2招教你预防扭伤
  7. scala数组入门到熟悉
  8. Android Q Labs| Android Q 分区存储
  9. 打开FOXMAIL常见错误提示“Message format error”
  10. 获取当前时间前3天的零点时间
  11. NTFS 数据流隐写学习
  12. 离线安装openOffice
  13. python爬虫cookie处理_Python爬虫(六)cookie相关的请求处理
  14. 2023年天津仁爱学院专升本报名确认缴费考试流程
  15. Windows GetLastError返回值 【转】
  16. dkp管理系统 php,RB!DKP v3.1.8 Build
  17. 海量文件、超大文件,如何实现高速传输?
  18. spark算子详细介绍(v、k-v、vv类型)
  19. 匹配追踪和正交匹配追踪
  20. 博通二合一蓝牙android驱动,Broadcom 博通 蓝牙与无线网卡一体-蓝牙3.0版驱动 for xp...

热门文章

  1. nginx基础概念(100%)之lingering_close
  2. 线程间通讯《代码》pthread_cond_wait/signal
  3. STM32H7---高速缓存Cache(二)
  4. 【STM32】HAL库 STM32CubeMX教程十一---DMA (串口DMA发送接收)
  5. 在c语言中下面的运算符中优先级最高的是,C语言习题请高手解答急急急1.下列运算符中优先级最高的运算符 爱问知识人...
  6. java iso-8859-1_如何在Java中的ISO-8859-1和UTF-8之间转换?
  7. Python3系列__01Python安装
  8. centos下安装opencv
  9. java数据库编程之JDBC
  10. 阅读构建之法10、11、12章