当前位置: 首页 > news >正文

常德网站建设专业品牌北京市建设工程信息网ic卡

常德网站建设专业品牌,北京市建设工程信息网ic卡,招聘网页制作课程设计,官渡网站设计制作作者#xff1a;lu人皆知 在APP做启动优化时#xff0c;Application会做一些初始化的工作#xff0c;但不要在Application中做耗时操作#xff0c;然而有些初始化工作可能是很耗时的#xff0c;那怎么办#xff1f;初始化操作可以开启子线程来完成。 计算执行时间 常规… 作者lu人皆知 在APP做启动优化时Application会做一些初始化的工作但不要在Application中做耗时操作然而有些初始化工作可能是很耗时的那怎么办初始化操作可以开启子线程来完成。 计算执行时间 常规方案手动埋点标记AOP方式获取 1、常规方案 常规方案就是在执行前埋点标记开始时间在执行后埋点标记结束时间然后计算开始时间和结束时间的差值时间差值就是耗时时间。 具体的耗时计算实现如下代码所示在 Application 中 onCreate 方法中调用了很多初始化的方法我们通过手动埋点标记的方式在每一个调用的方法内部都去计算其方法的耗时时间。 //Application.java Override public void onCreate() {initSharedPreference();initImageLoader();initSQLite();//..... }private void initSharedPreference() {long startTime System.currentTimeMillis();//init SharedPreferenceLog.d(TAG, initSharedPreference cost : (System.currentTimeMillis() - startTime)); }private void initImageLoader() {long startTime System.currentTimeMillis();Fresco.initialize(this);Log.d(TAG, initImageLoader cost : (System.currentTimeMillis() - startTime)); } private void initSQLite() {long startTime System.currentTimeMillis();//init buglyLog.d(TAG, initSQLite cost : (System.currentTimeMillis() - startTime)); }上面的计算方式是容易想到的实现方式但缺点也很明显 每个方法都是标记并计算耗时时间代码也不够优雅。对项目的入侵性很大工作量大。 2、AOP方式获取 AOP 就是我们常说的面向切面编程它可以针对同一类问题进行统一处理。 下面我们就来通过 AOP 的方式来优雅的获取Application每一个方法的执行时间。 2.1引入 AspectJ 在 Android 中通过 AspectJ 这个库来使用 AOP 接下来来引入这个库 在工程根 build.gradle 中引入 AspectJ 插件 classpath ‘com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4’ 在Module中 build.gradle 应用插件 apply plugin: ‘android-aspectjx’ 在Module中build.gradle 中引入 aspectj 库 implementation ‘org.aspectj:aspectjrt:1.8.9’ 2.2AOP的具体使用 定义一个类PerformanceAop使用Aspect注解Around(“execution(* com.lu.aop.MyApplication.**(…))”)表示需要对 MyApplication中的每一个方法都做 hook 处理。记录方法执行前后的时间戳并计算对应的时间差。 Aspect public class PerformanceAop {private static final String TAG PerformanceAop.class.getSimpleName();Around(execution(* com.lu.aop.MyApplication.**(..)))public void getTime(ProceedingJoinPoint joinPoint) {Signature signature joinPoint.getSignature();//得到方法的名字例如MyApplication.attachBaseContext(..)String name signature.toShortString();//记录方法执行前的时间戳long startTime System.currentTimeMillis();try {//执行该方法joinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}//记录执行该方法的时间long costTime System.currentTimeMillis() - startTime;Log.e(TAG, method name cost: costTime);} }运行结果 2019-08-18 17:09:12.946 10094-10094/com.lu.aop E/PerformanceAop: method MyApplication.attachBaseContext(..) cost:1 2019-08-18 17:09:12.979 10094-10094/com.lu.aop E/PerformanceAop: method MyApplication.initSQLite() cost:11 2019-08-18 17:09:13.002 10094-10094/com.lu.aop E/PerformanceAop: method MyApplication.initImageLoader() cost:17 2019-08-18 17:09:13.002 10094-10094/com.lu.aop E/PerformanceAop: method MyApplication.onCreate() cost:28AOP 这种方式是一个比较优雅的方式实现的它对已有代码是零侵入性的修改也方便。 用异步执行耗时任务 在 Application 去执行这些第三方库的初始化是会拖慢整个应用的启动过程的因此用子线程与主线程并行的方式来分担主线程的工作从而减少主线程的执行时间。 在子线程中执行任务 我们可能会容易想到以下这两种方式 方式一 public void onCreate(){new Thread() {public run() {//执行任务1//执行任务2//执行任务3}}.start();}方式二 public void onCreate(){new Thread() {public run() {//执行任务1}}.start();new Thread() {public run() {//执行任务2}}.start();new Thread() {public run() {//执行任务3}}.start(); }方式二更加充分地利用 CPU资源但是直接创建线程还是不够优雅所以使用线程池来管理这些线程会更好一些。 线程池管理 获取到对应的线程池但是这个线程个数不能随意填我们要能充分利用到 CPU 资源因此我们可以参考 AsyncTask 它是如何去设置核心线程数的。 Executors service Executors.newFixedThreadPool(核心线程个数);看到AsyncTask源码中了解核心线程数设置 private static final int CPU_COUNT Runtime.getRuntime().availableProcessors(); //CORE_POOL_SIZE 就是核心线程数 private static final int CORE_POOL_SIZE Math.max(2, Math.min(CPU_COUNT - 1, 4));这样我们就可以设置核心线程数了 //参考AsyncTask来设置线程的个数。 ExecutorService service Executors.newFixedThreadPool(CORE_POOL_SIZE);在MyApplication中实现异步执行任务 Override public void onCreate() {super.onCreate();//参考AsyncTask来设置线程的个数。ExecutorService service Executors.newFixedThreadPool(CORE_POOL_SIZE);service.submit(new Runnable() {Overridepublic void run() {initSQLite();}});service.submit(new Runnable() {Overridepublic void run() {initImageLoader();}}); }异步加载的代码执行结果 2019-08-18 19:09:38.022 13948-13948/com.lu.aop E/PerformanceAop: method MyApplication.attachBaseContext(..) cost:1 2019-08-18 19:09:38.062 13948-13948/com.lu.aop E/PerformanceAop: method MyApplication.onCreate() cost:4 2019-08-18 19:09:38.078 13948-13967/com.lu.aop E/PerformanceAop: method MyApplication.initSQLite() cost:9 2019-08-18 19:09:38.094 13948-13968/com.lu.aop E/PerformanceAop: method MyApplication.initImageLoader() cost:15从Log日志数据对比可以看出主线程执行的 onCreate 方法的执行时间从原来的 28ms 减到到了 4ms 。所以用子线程执行耗时任务还是相当好的。但是到这里又遇到一个问题就是有一些方法是必须在 Application onCreate 执行完成之前完成初始化的因为在 MainActivity 中就需要使用到那我们上面的异步就会有问题了那如何解决这个问题呢 异步任务必须在某一个阶段执行完成 以initImageLoader()为例不知道Application中的子线程什么时候才完成初始化任务但是这个时候已经进入了MainActivity了用到ImageLoaderImageLoader在Application中还没有完成初始化就用不了所以得控制ImageLoader在 Application onCreate 执行完成之前完成初始化。这时就需要使用到 CountDownLatch 了。 CountDownLatch是一种java.util.concurrent包下一个同步工具类它允许一个或多个线程等待直到在其他线程中一组操作执行完成。 在Application中定义CountDownLatch //Application private CountDownLatch countDownLatch new CountDownLatch(1);在initImageLoader方法中执行完毕时执行 countDownLatch.countDown() private void initImageLoader() {Fresco.initialize(this);//try {//模拟耗时//Thread.sleep(3000);//} catch (Exception e) {// e.printStackTrace();//}//Log.e(TAG, 初始化initImageLoader完毕);//数量减一countDownLatch.countDown();}等待 countDownLatch.await() 在 onCreate 方法结束点等待如果在此处之前之前调用了countDownLatch.countDown()那么就直接跳过否则就在此等待。 public void onCreate() {super.onCreate();//参考AsyncTask来设置线程的个数。ExecutorService service Executors.newFixedThreadPool(CORE_POOL_SIZE);service.submit(new Runnable() {Overridepublic void run() {initSQLite();}});service.submit(new Runnable() {Overridepublic void run() {initImageLoader();}});//在 onCreate 方法中等待如果在此处之前之前调用了countDownLatch.countDown()那么就直接跳过否则就在此等待。try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}Log.e(TAG, Application onCreate 执行完毕); }这样我们的 Application onCreate 方法就会等待异步任务 initImageLoader 执行完毕之后才会结束 onCreate 这个方法的生命周期。 总结 了解计算执行任务时间了解AOP面向切面编程知识了解AsyncTask的核心线程数及运用学习了初始化数据时异步优化方案 为了帮助到大家更好的全面清晰的掌握好性能优化准备了相关的核心笔记还该底层逻辑https://qr18.cn/FVlo89 性能优化核心笔记https://qr18.cn/FVlo89 启动优化 内存优化 UI优化 网络优化 Bitmap优化与图片压缩优化https://qr18.cn/FVlo89 多线程并发优化与数据传输效率优化 体积包优化 《Android 性能监控框架》https://qr18.cn/FVlo89 《Android Framework学习手册》https://qr18.cn/AQpN4J 开机Init 进程开机启动 Zygote 进程开机启动 SystemServer 进程Binder 驱动AMS 的启动过程PMS 的启动过程Launcher 的启动过程Android 四大组件Android 系统服务 - Input 事件的分发过程Android 底层渲染 - 屏幕刷新机制源码分析Android 源码分析实战
http://www.dnsts.com.cn/news/13169.html

相关文章:

  • 如何自己建设简单的手机网站个人站长怎么样做网站才不会很累
  • 华丽的网站模板1688阿里巴巴国际站首页
  • 成功的网站设计wordpress常用主题
  • 邵阳市网站建设杭州市住房和城乡建设局
  • 河南郑州网站制作公司如何做网站制作
  • 网站建设.pdf百度云东莞市网站建设分站企业
  • 网站互点可以自己点么flash网站在线diy源码
  • 聚合猫网站建设地方志网站建设
  • 网站页脚怎么做做服装网站需要什么
  • 网站换了域名做跳转做文字图网站
  • 山西建设网站的公司网站开发需要那些人才
  • 广州商务网站建设delphi可以做网站吗
  • wordpress做的著名网站电商网站如何做优化
  • 做网站需要提供的资料大连建设工业产品网站
  • 天台建设局网站西安市建设工程信息网诚信平台
  • 广州市 住房建设局网站高端的咨询行业网站策划
  • 刚做的网站怎么快速搜索到wordpress攻防
  • 沈阳制作网站的人建设一个旅游电子商务网站
  • 网站推广需要几个人做商城网站定制建设价位
  • 那个网站教人做冰点关键词排名seo
  • 珠海购物网站制作仿百度文库网站源码商业版dedecms(梦织)系统内核
  • 找人做个网站多少钱专业团队打造专业品质
  • 物流公司在哪做网站如何制作企业内部网站
  • 做软件常用的网站五莲网站建设报价
  • 网站上的在线答题是怎么做的wordpress 视频页面
  • 修改散文网站网站开发设计合同
  • 工程信息价在哪查询江西做网站优化好的
  • 棋牌网站开发多少钱如何做网站刷题
  • 手机网站建设分析淘宝网页制作模板
  • 经典 网站沈阳建站模板