中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

西安企業(yè)網(wǎng)站建站全球搜效果怎么樣

西安企業(yè)網(wǎng)站建站,全球搜效果怎么樣,哈爾濱調(diào)整部分地區(qū)風(fēng)險(xiǎn)等級(jí),網(wǎng)站收錄在哪里可以查看作者:lu人皆知 在APP做啟動(dòng)優(yōu)化時(shí),Application會(huì)做一些初始化的工作,但不要在Application中做耗時(shí)操作,然而有些初始化工作可能是很耗時(shí)的,那怎么辦?初始化操作可以開啟子線程來完成。 計(jì)算執(zhí)行時(shí)間 常規(guī)…

作者:lu人皆知

在APP做啟動(dòng)優(yōu)化時(shí),Application會(huì)做一些初始化的工作,但不要在Application中做耗時(shí)操作,然而有些初始化工作可能是很耗時(shí)的,那怎么辦?初始化操作可以開啟子線程來完成。

計(jì)算執(zhí)行時(shí)間

  • 常規(guī)方案(手動(dòng)埋點(diǎn)標(biāo)記)
  • AOP方式獲取

1、常規(guī)方案

常規(guī)方案就是在執(zhí)行前埋點(diǎn)標(biāo)記開始時(shí)間,在執(zhí)行后埋點(diǎn)標(biāo)記結(jié)束時(shí)間,然后計(jì)算開始時(shí)間和結(jié)束時(shí)間的差值,時(shí)間差值就是耗時(shí)時(shí)間。

具體的耗時(shí)計(jì)算實(shí)現(xiàn)如下代碼所示,在 Application 中 onCreate 方法中調(diào)用了很多初始化的方法,我們通過手動(dòng)埋點(diǎn)標(biāo)記的方式在每一個(gè)調(diào)用的方法內(nèi)部都去計(jì)算其方法的耗時(shí)時(shí)間。

//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));    
}

上面的計(jì)算方式,是容易想到的實(shí)現(xiàn)方式,但缺點(diǎn)也很明顯:

  • 每個(gè)方法都是標(biāo)記并計(jì)算耗時(shí)時(shí)間,代碼也不夠優(yōu)雅。
  • 對(duì)項(xiàng)目的入侵性很大,工作量大。

2、AOP方式獲取

AOP 就是我們常說的面向切面編程,它可以針對(duì)同一類問題進(jìn)行統(tǒng)一處理。

下面我們就來通過 AOP 的方式來優(yōu)雅的獲取Application每一個(gè)方法的執(zhí)行時(shí)間。

2.1引入 AspectJ

在 Android 中通過 AspectJ 這個(gè)庫來使用 AOP ,接下來來引入這個(gè)庫:

  • 在工程根 build.gradle 中引入 AspectJ 插件
    • classpath ‘com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4’
  • 在Module中 build.gradle 應(yīng)用插件
    • apply plugin: ‘a(chǎn)ndroid-aspectjx’
  • 在Module中build.gradle 中引入 aspectj 庫
    • implementation ‘org.aspectj:aspectjrt:1.8.9’

2.2AOP的具體使用

  • 定義一個(gè)類PerformanceAop使用@Aspect注解
  • @Around(“execution(* com.lu.aop.MyApplication.**(…))”)表示需要對(duì) MyApplication中的每一個(gè)方法都做 hook 處理。
  • 記錄方法執(zhí)行前后的時(shí)間戳,并計(jì)算對(duì)應(yīng)的時(shí)間差。
@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();//記錄方法執(zhí)行前的時(shí)間戳long startTime = System.currentTimeMillis();try {//執(zhí)行該方法joinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}//記錄執(zhí)行該方法的時(shí)間long costTime = System.currentTimeMillis() - startTime;Log.e(TAG, "method " + name + " cost:" + costTime);}
}

運(yùn)行結(jié)果
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:28

AOP 這種方式是一個(gè)比較優(yōu)雅的方式實(shí)現(xiàn)的,它對(duì)已有代碼是零侵入性的,修改也方便。

用異步執(zhí)行耗時(shí)任務(wù)

在 Application 去執(zhí)行這些第三方庫的初始化,是會(huì)拖慢整個(gè)應(yīng)用的啟動(dòng)過程的,因此用子線程與主線程并行的方式來分擔(dān)主線程的工作,從而減少主線程的執(zhí)行時(shí)間。

在子線程中執(zhí)行任務(wù)

我們可能會(huì)容易想到以下這兩種方式:

  • 方式一
  public void onCreate(){new Thread() {public run() {//執(zhí)行任務(wù)1//執(zhí)行任務(wù)2//執(zhí)行任務(wù)3}}.start();}
  • 方式二
public void onCreate(){new Thread() {public run() {//執(zhí)行任務(wù)1}}.start();new Thread() {public run() {//執(zhí)行任務(wù)2}}.start();new Thread() {public run() {//執(zhí)行任務(wù)3}}.start();
}

方式二更加充分地利用 CPU資源,但是直接創(chuàng)建線程還是不夠優(yōu)雅,所以使用線程池來管理這些線程會(huì)更好一些。

線程池管理

獲取到對(duì)應(yīng)的線程池,但是這個(gè)線程個(gè)數(shù)不能隨意填,我們要能充分利用到 CPU 資源,因此我們可以參考 AsyncTask 它是如何去設(shè)置核心線程數(shù)的。

Executors service = Executors.newFixedThreadPool(核心線程個(gè)數(shù));

看到AsyncTask源碼中了解核心線程數(shù)設(shè)置

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//CORE_POOL_SIZE 就是核心線程數(shù)
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));

這樣我們就可以設(shè)置核心線程數(shù)了

//參考AsyncTask來設(shè)置線程的個(gè)數(shù)。
ExecutorService service = Executors.newFixedThreadPool(CORE_POOL_SIZE);

在MyApplication中實(shí)現(xiàn)異步執(zhí)行任務(wù):

@Override
public void onCreate() {super.onCreate();//參考AsyncTask來設(shè)置線程的個(gè)數(shù)。ExecutorService service = Executors.newFixedThreadPool(CORE_POOL_SIZE);service.submit(new Runnable() {@Overridepublic void run() {initSQLite();}});service.submit(new Runnable() {@Overridepublic void run() {initImageLoader();}});
}

異步加載的代碼執(zhí)行結(jié)果
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日志數(shù)據(jù)對(duì)比,可以看出主線程執(zhí)行的 onCreate 方法的執(zhí)行時(shí)間從原來的 28ms 減到到了 4ms 。所以用子線程執(zhí)行耗時(shí)任務(wù)還是相當(dāng)好的。但是到這里又遇到一個(gè)問題,就是有一些方法是必須在 Application onCreate 執(zhí)行完成之前完成初始化的,因?yàn)樵?MainActivity 中就需要使用到,那我們上面的異步就會(huì)有問題了,那如何解決這個(gè)問題呢?

異步任務(wù)必須在某一個(gè)階段執(zhí)行完成

以initImageLoader()為例,不知道Application中的子線程什么時(shí)候才完成初始化任務(wù),但是這個(gè)時(shí)候已經(jīng)進(jìn)入了MainActivity了,用到ImageLoader,ImageLoader在Application中還沒有完成初始化就用不了,所以得控制ImageLoader在 Application onCreate 執(zhí)行完成之前完成初始化。這時(shí)就需要使用到 CountDownLatch 了。

CountDownLatch是一種java.util.concurrent包下一個(gè)同步工具類,它允許一個(gè)或多個(gè)線程等待直到在其他線程中一組操作執(zhí)行完成。

  • 在Application中定義CountDownLatch
//Application
private CountDownLatch countDownLatch = new CountDownLatch(1);
  • 在initImageLoader方法中執(zhí)行完畢時(shí),執(zhí)行 countDownLatch.countDown()
private void initImageLoader() {Fresco.initialize(this);//try {//模擬耗時(shí)//Thread.sleep(3000);//} catch (Exception e) {// e.printStackTrace();//}//Log.e(TAG, "初始化initImageLoader完畢");//數(shù)量減一countDownLatch.countDown();}
  • 等待 countDownLatch.await()

在 onCreate 方法結(jié)束點(diǎn)等待,如果在此處之前之前調(diào)用了countDownLatch.countDown(),那么就直接跳過,否則就在此等待。

public void onCreate() {super.onCreate();//參考AsyncTask來設(shè)置線程的個(gè)數(shù)。ExecutorService service = Executors.newFixedThreadPool(CORE_POOL_SIZE);service.submit(new Runnable() {@Overridepublic void run() {initSQLite();}});service.submit(new Runnable() {@Overridepublic void run() {initImageLoader();}});//在 onCreate 方法中等待,如果在此處之前之前調(diào)用了countDownLatch.countDown(),那么就直接跳過,否則就在此等待。try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}Log.e(TAG, "Application onCreate 執(zhí)行完畢");
}

這樣,我們的 Application onCreate 方法就會(huì)等待異步任務(wù) initImageLoader 執(zhí)行完畢之后才會(huì)結(jié)束 onCreate 這個(gè)方法的生命周期。

總結(jié)

  • 了解計(jì)算執(zhí)行任務(wù)時(shí)間
  • 了解AOP面向切面編程知識(shí)
  • 了解AsyncTask的核心線程數(shù)及運(yùn)用
  • 學(xué)習(xí)了初始化數(shù)據(jù)時(shí)異步優(yōu)化方案

為了幫助到大家更好的全面清晰的掌握好性能優(yōu)化,準(zhǔn)備了相關(guān)的核心筆記(還該底層邏輯):https://qr18.cn/FVlo89

性能優(yōu)化核心筆記:https://qr18.cn/FVlo89

啟動(dòng)優(yōu)化

內(nèi)存優(yōu)化

UI優(yōu)化

網(wǎng)絡(luò)優(yōu)化

Bitmap優(yōu)化與圖片壓縮優(yōu)化https://qr18.cn/FVlo89

多線程并發(fā)優(yōu)化與數(shù)據(jù)傳輸效率優(yōu)化

體積包優(yōu)化

《Android 性能監(jiān)控框架》:https://qr18.cn/FVlo89

《Android Framework學(xué)習(xí)手冊(cè)》:https://qr18.cn/AQpN4J

  1. 開機(jī)Init 進(jìn)程
  2. 開機(jī)啟動(dòng) Zygote 進(jìn)程
  3. 開機(jī)啟動(dòng) SystemServer 進(jìn)程
  4. Binder 驅(qū)動(dòng)
  5. AMS 的啟動(dòng)過程
  6. PMS 的啟動(dòng)過程
  7. Launcher 的啟動(dòng)過程
  8. Android 四大組件
  9. Android 系統(tǒng)服務(wù) - Input 事件的分發(fā)過程
  10. Android 底層渲染 - 屏幕刷新機(jī)制源碼分析
  11. Android 源碼分析實(shí)戰(zhàn)

http://www.risenshineclean.com/news/2402.html

相關(guān)文章:

  • 上海 網(wǎng)站建設(shè) 外包百度教育app
  • 中山網(wǎng)站建設(shè)文化機(jī)構(gòu)域名批量查詢注冊(cè)
  • yeti2.0 wordpress主題怎么優(yōu)化自己網(wǎng)站
  • 企業(yè)畫冊(cè)設(shè)計(jì)排版360優(yōu)化大師最新版的功能
  • 大良營銷網(wǎng)站建設(shè)平臺(tái)北京百度seo點(diǎn)擊器
  • 網(wǎng)站建設(shè)招標(biāo)2017seo短期培訓(xùn)班
  • 企業(yè)網(wǎng)站建設(shè)合同范本平板電視seo優(yōu)化關(guān)鍵詞
  • 建站費(fèi)用報(bào)價(jià)單崇左網(wǎng)站建設(shè)
  • 如何把網(wǎng)站做成軟件哈爾濱百度推廣公司
  • 英語培訓(xùn)網(wǎng)站模板亞馬遜seo是什么意思
  • 原創(chuàng)小說網(wǎng)站建設(shè)源碼百度seo公司哪家最好
  • 深圳哪個(gè)做網(wǎng)站好優(yōu)化唐山公司做網(wǎng)站
  • 公司網(wǎng)站域名管理中國50強(qiáng)企業(yè)管理培訓(xùn)機(jī)構(gòu)
  • 高端做網(wǎng)站廣東vs北京首鋼
  • 免費(fèi)設(shè)計(jì)自己的名字合肥網(wǎng)站推廣優(yōu)化公司
  • vps 部署wordpressseo攻略
  • 建設(shè)網(wǎng)站過程seo網(wǎng)絡(luò)推廣有哪些
  • 做網(wǎng)站建設(shè)推廣好做嗎營銷軟件培訓(xùn)
  • 換模板搭建網(wǎng)站怎么做營銷100個(gè)引流方案
  • 佛山網(wǎng)站建設(shè)專家長沙企業(yè)seo服務(wù)
  • 遼寧省住房和城鄉(xiāng)建設(shè)廳網(wǎng)站進(jìn)不去長春網(wǎng)站制作公司
  • 做網(wǎng)站模板賺錢關(guān)鍵詞優(yōu)化計(jì)劃
  • 鋼模板規(guī)格尺寸及厚度百度網(wǎng)站怎么優(yōu)化排名靠前
  • 龍采網(wǎng)站建設(shè)揚(yáng)州整站seo
  • 廣州市品牌網(wǎng)站建設(shè)服務(wù)機(jī)構(gòu)電商網(wǎng)絡(luò)推廣怎么做
  • 河南鄭州網(wǎng)站制作公司百度seo營銷
  • 中文網(wǎng)站建設(shè)中模板下載全網(wǎng)熱搜榜第一名
  • 網(wǎng)站案例seo網(wǎng)站優(yōu)化價(jià)格
  • 局域網(wǎng)創(chuàng)建網(wǎng)站路由器優(yōu)化大師
  • 重慶網(wǎng)站推廣外包企業(yè)競(jìng)價(jià)推廣培訓(xùn)課程