一竟终、 Java基礎(chǔ)
1、集合
1.1 List(有序疗锐、可重復(fù))
List里存放的對象是有序的颊咬,同時(shí)也是可以重復(fù)的,List關(guān)注的是索引趋距,擁有一系列和索引相關(guān)的方法粒氧,查詢速度快。查詢效率高节腐,刪除與插入效率低外盯,會引起元素位置變化;
(1) ArrayList 基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)翼雀,查改效率高饱苟, 增刪效率低;
(2) LinkedList 基于雙向循環(huán)鏈表實(shí)現(xiàn)狼渊,增刪操作效率更高箱熬,而查改操作效率較低;
(3) Vector 跟ArrayList相似狈邑,線程安全城须;
1.2 Set(無序、不能重復(fù))
Set里存放的對象是無序米苹,不能重復(fù)的糕伐,集合中的對象不按特定的方式排序,只是簡單地把對象加入集合中蘸嘶。刪除和插入效率高良瞧,不會引起元素位置變化
(1) HashSet 不允許出現(xiàn)重復(fù)元素,不保證集合中元素的順序训唱,允許包含值為null的元素褥蚯,最多一個;
(2) ThreeSet 可以實(shí)現(xiàn)排序等功能,底層是二叉樹
1.3 Map(鍵值對况增、鍵唯一赞庶、值不唯一)
Map集合中存儲的是鍵值對,鍵不能重復(fù),值可以重復(fù)尘执。根據(jù)鍵得到值舍哄,對map集合遍歷時(shí)先得到鍵的set集合,對set集合進(jìn)行遍歷誊锭,得到相應(yīng)的值表悬。
(1) HashMap 根據(jù)鍵的HashCode值存儲數(shù)據(jù),根據(jù)鍵可以直接獲取它的值丧靡,具有很快的訪問速度蟆沫,遍歷時(shí),取得數(shù)據(jù)的順序是完全隨機(jī)的温治。因?yàn)殒I對象不可以重復(fù)饭庞,所以HashMap最多只允許一條記錄的鍵為Null,允許多條記錄的值為Null熬荆,是非同步的
(2) TreeMap 實(shí)現(xiàn)SortMap接口舟山,能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按鍵值的升序排序(自然順序)卤恳,也可以指定排序的比較器累盗,當(dāng)用Iterator遍歷TreeMap時(shí),得到的記錄是排過序的突琳。不允許key值為空若债,非同步的;
2拆融、繼承
從已有的類中派生出已有的類蠢琳,繼承來的類能吸收已有類的非私有屬性和方法(行為),并能擴(kuò)展新的屬性和方法镜豹。通俗來說傲须,繼承就是分為了父類和子類,父類有時(shí)也成為超類(super class)逛艰,子類又成為派生類躏碳;子類繼承了父類的屬性和方法,并且具有了父類所沒有的散怖。
4.1 限制
(1)Java的繼承只能是單繼承,一個子類只能繼承一個父類肄渗;
(2)Java的繼承允許多層繼承镇眷,即子類又是另一個類的父類(可以理解 為爺爺、爸爸與兒子的關(guān)系)翎嫡;
3欠动、多態(tài)
指父類的某個方法被子類重寫時(shí),可以產(chǎn)生自己的功能行為,同一個操作 作用于不同對象具伍,可以有不同的解釋翅雏,產(chǎn)生不同的執(zhí)行結(jié)果。
5.1 三個必要條件:繼承父類人芽、重寫父類的方法和父類的引用指向子類對象;
5.2 作用:消除類型之間的耦合關(guān)系, 多個方法在不同對象執(zhí)行不同的結(jié)果;
4望几、接口
是抽象類的延伸,它允許一個類可以實(shí)現(xiàn)多個接口萤厅,彌補(bǔ)了抽象類不能多繼承的缺陷橄抹,接口是對類的描述,使用 interface 關(guān)鍵字來聲明惕味。
5楼誓、線程池 --待補(bǔ)充
二、 Koltin基礎(chǔ)
kotlin語言更簡單名挥。能減少代碼的冗余以及一些Java不支持的特性
獨(dú)有的特性:
1.空指針安全
2.操作符重載
3.協(xié)程
4.Range 表達(dá)式
5.智能轉(zhuǎn)換
6.伴隨體
優(yōu)勢:
數(shù)據(jù)類型 toString, hashcode, equals Setter 和getter都省略
Kotlin支持?jǐn)U展函數(shù)
空指針安全
自帶單例(object)
劣勢:
沒有檢查異常疟羹、原始類型、 靜態(tài)成員禀倔、 非私有字段榄融、 通配符類型、 三元操作符蹋艺;
沒有明顯意義的關(guān)鍵字( internal, crossinline, expect, reified, sealed, open)剃袍;
Kotlin有沒有static 關(guān)鍵字,用伴隨體代替捎谨;
協(xié)程
協(xié)程是輕量級線程民效,創(chuàng)建協(xié)程不需要分配新的線程,相反涛救,它使用已經(jīng)定義好的線程池畏邢,智能調(diào)度。此外检吆,協(xié)程可以掛起和恢復(fù)舒萎;
三、 Android
各大版本之間的特點(diǎn):
android 5.0 Material Design視覺工具包蹭沛、鎖屏顯示通知
android 6.0 動態(tài)權(quán)限臂寝、文本選擇(剪切、復(fù)制摊灭、全選)
android 7.0 應(yīng)用分屏咆贬、通知欄快捷回復(fù)
android 8.0 畫中畫(視頻小窗口)、自適應(yīng)圖標(biāo)(圓形或方形)
android 9.0 劉海屏帚呼、凹凸屏的適配和多攝像頭支持
android 10 可折疊設(shè)備支持掏缎、5G網(wǎng)絡(luò)皱蹦、設(shè)備標(biāo)識碼和地理位置權(quán)限
3.1 網(wǎng)絡(luò)請求
- 網(wǎng)絡(luò)
1.1 HTTP與HTTP協(xié)議
Get不能大于2kb,執(zhí)行效率高眷蜈,不太安全沪哺;Post無限制,執(zhí)行效率低酌儒,更安全辜妓;
執(zhí)行效率低的原因是Post需求組裝鍵值對放入header中,get直接拼接即可今豆;
1.2 Okhttp
它內(nèi)部實(shí)現(xiàn)通過一個責(zé)任鏈模式完成嫌拣,將網(wǎng)絡(luò)請求的各個階段封裝到各個鏈條中,實(shí)現(xiàn)了各層的解耦呆躲。
1.3 Retrofit2 更詳細(xì)的參考
它并不是網(wǎng)絡(luò)請求框架异逐,嚴(yán)格說只是對網(wǎng)絡(luò)請求的一種封裝,我們只需要定義一個接口類插掂,在請求方法上加上相應(yīng)的注解灰瞻,甚至都不需要實(shí)現(xiàn),就可以實(shí)現(xiàn)網(wǎng)絡(luò)請求辅甥。
3.2 開發(fā)模式
(1) MVC
Model:針對業(yè)務(wù)模型建立的數(shù)據(jù)結(jié)構(gòu)和類(與View無關(guān)酝润,只與業(yè)務(wù)相關(guān))
View:XML/JAVA或者JS+HTML進(jìn)行頁面的顯示。Activity/Frgament也承擔(dān)了View的功能璃弄。
Controller:Android的控制層通常在Activity要销、Fragment之中。本質(zhì)就是Controller操作Model層的數(shù)據(jù)夏块,并且將數(shù)據(jù)返回給View層展示疏咐。
缺點(diǎn):View層和Model層互相耦合,耦合過重,代碼量過大脐供,不易于開發(fā)和維護(hù)浑塞。
(2) MVP
Model:對數(shù)據(jù)和網(wǎng)絡(luò)等的操作,主要提供數(shù)據(jù)的存儲功能政己。Presenter需要通過Model存取數(shù)據(jù)酌壕。
View: 負(fù)責(zé)處理點(diǎn)擊事件和視圖展示(Activity、Fragment或者某個View控件)
Presenter: View和Model之間的橋梁歇由,從Model檢索數(shù)據(jù)后返回給View層卵牍。使得M/V之間不再有耦合關(guān)系。
缺點(diǎn): view層和presenter層沦泌,如果有一個邏輯很復(fù)雜的頁面辽慕,接口會有很多,導(dǎo)致維護(hù)接口的成本非常大赦肃,解決方案是盡可能將一些通用的接口作為基類,其他的接口去繼承。
(3) MVVM
View:對應(yīng)于Activity和XML他宛,負(fù)責(zé)View的繪制以及與用戶交互船侧,它是不能做任何與業(yè)務(wù)相關(guān)的操作。
Model:實(shí)體模型厅各,這跟咱們平常定義的Model層是不一樣的镜撩。
ViewModel:負(fù)責(zé)完成View與Model之間的交互,負(fù)責(zé)業(yè)務(wù)邏輯队塘。它不能做任何與UI相關(guān)的操作袁梗,也就是不能持有任何View的引用。
ViewModel和Model/View進(jìn)行了雙向綁定憔古。
View發(fā)生改變時(shí)遮怜,ViewModel會通知Model進(jìn)行更新數(shù)據(jù),Model數(shù)據(jù)更新后鸿市,ViewModel會通知View更新顯示锯梁。支持庫Data Binding:能將數(shù)據(jù)綁定到xml中,現(xiàn)在又引入了ViewModel和LiveData組件用于更方便的實(shí)現(xiàn)MVVM
3.3 圖片壓縮
(1) 常規(guī)壓縮
①質(zhì)量壓縮
在保持像素的前提下改變圖片的位深及透明度(即:通過算法抹掉(同化)圖片中的一些某點(diǎn)附近 相近的像素)達(dá)到降低質(zhì)量壓縮文件的目的焰情。
②尺寸壓縮
通過減少單位尺寸的像素值陌凳,真正意義上的降低像素(通過縮放圖片像素來減少圖片占用內(nèi)存大小)
③采樣率壓縮
設(shè)置圖片的采樣率内舟,降低圖片像素合敦。好處是不會先將大圖片讀入內(nèi)存,大大減少了內(nèi)存的使用验游,也不必考慮將大圖片讀入內(nèi)存后的釋放事宜充岛。 帶來的問題是因?yàn)椴蓸勇适钦麛?shù),所以不能很好的保證圖片的質(zhì)量批狱。如我們需要的是在2和3采樣率之間裸准,用2的話圖片就大了一點(diǎn),但是用3的話圖片質(zhì)量就會有很明顯的下降赔硫,這樣也無法完全滿足我的需要炒俱。
④通過JIN調(diào)用libjpeg庫壓縮
繞過Android Bitmap API層,自己編碼實(shí)現(xiàn)—-修復(fù)使用哈夫曼算法爪膊。
(2). 魯班壓縮
① 核心方法就是thirdCompress(File file)权悟,即如何計(jì)算得出理想的壓縮后寬高,以及圖片大型剖ⅰ峦阁;
② 不足之處: 不能很好的支持多圖片壓縮,會產(chǎn)生OOM耘成;與RxJava強(qiáng)耦合榔昔。
3.5 自定義View
View的繪制流程 和 步驟
3.6 事件分發(fā)
基本會遵從 Activity => ViewGroup => View 的順序進(jìn)行事件分發(fā)驹闰,然后通過調(diào)用 onTouchEvent() 方法進(jìn)行事件的處理。我們在項(xiàng)目中一般會對 MotionEvent.ACTION_DOWN撒会,MotionEvent.ACTION_UP嘹朗,MotionEvent.ACTION_MOVE,MotionEvent.ACTION_CANCEL 分情況進(jìn)行操作
3.7 性能優(yōu)化
(1) 啟動優(yōu)化: Application中不要做大量耗時(shí)操作,如果必須的話诵肛,建議異步做耗時(shí)操作
(2) 布局優(yōu)化:使用合理的控件選擇屹培,少嵌套。(合理使用include,merge,viewStub等使用)
(3) Apk優(yōu)化(資源文件優(yōu)化怔檩,代碼優(yōu)化, lint檢查褪秀,.9.png, 合理使用shape替代圖片,webp等)
(4) 網(wǎng)絡(luò)優(yōu)化薛训,電量優(yōu)化
避免輪詢媒吗,盡量使用推送。
應(yīng)用處于后臺時(shí)许蓖,禁用某些數(shù)據(jù)傳輸
限制訪問頻率蝴猪,失敗后不要無限重連
選用合適的定位服務(wù)(GPS定位,網(wǎng)絡(luò)定位膊爪,被動定位)
使用緩存
startActivityForResult替代發(fā)送廣播
(5) 內(nèi)存優(yōu)化
循環(huán)盡量不使用局部變量
避免在onDraw中創(chuàng)建對象自阱,onDraw會被頻繁調(diào)用,容易造成內(nèi)存抖動米酬。循環(huán)中創(chuàng)建大的對象沛豌,也是如此。
不用的對象及時(shí)釋放
數(shù)據(jù)庫的cursor及時(shí)關(guān)閉
Adapter使用緩存
注冊廣播后赃额,在生命周期結(jié)束時(shí)反注冊
及時(shí)關(guān)閉流操作
圖片盡量使用軟引用加派,較大的圖片可以通過bitmapFactory縮放后再使用,并及時(shí)recycler跳芳。另外加載巨圖時(shí)不要 使用setImageBitmap或setImageResourse或BitmapFactory.decodeResource,這些方法拿到的都是bitmap的對象芍锦,占用內(nèi)存較大》膳瑁可以用BitmapFactory.decodeStream方法配合BitmapFactory.Options進(jìn)行縮放
避免static成員變量引用資源耗費(fèi)過多實(shí)例
避免靜態(tài)內(nèi)部類的引用
3.8 異常問題
(1) OOM
out of memory 內(nèi)存溢出 娄琉。
每個進(jìn)程能夠支配的內(nèi)存是有限的,所以資源要記得使用完及時(shí)釋放吓歇,如果未釋放孽水,就有可能造成內(nèi)存泄漏,內(nèi)存泄漏達(dá)到一定程度 手機(jī)就會造成內(nèi)存溢出城看。
內(nèi)存泄漏和內(nèi)存溢出是不同的女气,但是過多的內(nèi)存泄漏會導(dǎo)致內(nèi)存溢出。
內(nèi)存溢出的根本原因:
1.應(yīng)用申請內(nèi)存的速度超過了gc內(nèi)存回收的速度测柠。
2.應(yīng)用申請的內(nèi)存大小超過了手機(jī)的可用內(nèi)存炼鞠。
常見根因:
1.加載超大的圖片缘滥、文件
2.創(chuàng)建大量的對象
優(yōu)化方法:
1.申請更大的內(nèi)存,比如多進(jìn)程簇搅、設(shè)置manifest中的largeHeap=true等完域。
2.減少內(nèi)存使用
①使用優(yōu)化后的集合對象,分場景使用SpaseArray和HashMap瘩将;
②使用微信的mmkv替代sharedpreference;
③使用StringBuilder替代String拼接
④統(tǒng)一帶有緩存的基礎(chǔ)庫凹耙,特別是圖片庫姿现,如果用了兩套不一樣的圖片加載庫就會出現(xiàn)2個圖片各自維護(hù)一套圖片緩存
⑤給ImageView設(shè)置合適尺寸的圖片,列表頁顯示縮略圖肖抱,查看大圖顯示原圖
⑥優(yōu)化業(yè)務(wù)架構(gòu)設(shè)計(jì)备典,比如省市區(qū)數(shù)據(jù)分批加載,需要加載省就加載省意述,需要加載市就加載失去提佣,避免一下子加載所有數(shù)據(jù)
3.避免內(nèi)存泄漏
(2)ANR和卡頓
(3)過渡繪制
(4)靜態(tài)代碼檢測
3.9 屏幕適配
(1) 一般來說主要針對屏幕適配,最小寬度適配和今日頭條density適配
(2) 權(quán)限適配荤崇,安卓6.0的運(yùn)行時(shí)權(quán)限拌屏,這里有坑,6.0以前术荤,Vivo有i管家進(jìn)行權(quán)限管理倚喂,魅族自帶有權(quán)限管理,還有其他第三方軟件進(jìn)行權(quán)限限制瓣戚,導(dǎo)致權(quán)限不可用
(3) 異形屏幕適配端圈,一般來說都是劉海,水滴子库,挖孔部分不進(jìn)行使用或者就直接不管不顯示缺失部分舱权,可以滿足大部分需求,小部分需求需要使用異形部分的需要按手機(jī)型號進(jìn)行特定適配仑嗅,官網(wǎng)都有適配方法
(4) 安卓系統(tǒng)適配宴倍,及時(shí)關(guān)注新系統(tǒng)新特性,使情況修改targetSdk
(5) 語言无畔,Left Right和Start End啊楚,這些適配基本不需要太大關(guān)注
(6) “和ios一樣”,口才或者腦細(xì)胞適配浑彰,能說服就下班恭理,不能就加班
3.10 音視頻
視頻播放器的封裝
對三方庫GSYVideoPlayer進(jìn)行二次封裝,基于B站的IJKPlayer內(nèi)核(兼容系統(tǒng)MediaPlayer與EXOPlayer2郭变,支持h263\4\5颜价、Https涯保、concat、rtsp周伦、hls夕春、rtmp、crypto专挪、mpeg等協(xié)議, 自定義內(nèi)容:
(1) 邊播放邊緩存
(2) 廣告和彈幕
(3) 滑動播放(抖音樣式)
(4) 列表播放
(5) 實(shí)時(shí)和非實(shí)時(shí)播放
(6) 小屏播放
(7) 自定義UI, 包括: 觸摸亮度和音量, 快進(jìn)與快退, 橫豎屏切換, 倒計(jì)時(shí)等等
騰訊直播SDK
(1) 推流和拉流
(2) 消息并發(fā)及志,設(shè)置閾值
(3) 自定義ui,點(diǎn)贊等
音頻
即時(shí)通寨腔、聽書類app涉及音頻開發(fā)速侈,通過系統(tǒng)MediaRecord、MediaPlay處理音頻的錄制迫卢、播放倚搬。
(1) mp3/wav/ogg/amr/aac等格式
(2) 音量與波浪圖同步
(3) 播放進(jìn)度回調(diào),實(shí)時(shí)更新ui
(4) 綁定頁面生命周期乾蛤,鎖屏播放mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK
3.11 發(fā)版
1.檢查數(shù)據(jù)庫版本更新, 重點(diǎn)看下新增字段是否進(jìn)行升級處理, 防止App崩潰;
2..使用versionName自增每界,處理強(qiáng)更版本要單獨(dú)聲明一個版本號,防止老版本跨版本更新家卖;
3.開啟混淆眨层,保留mapping映射表,若安全方面要求比較高篡九,可以再對APK進(jìn)行安全加固谐岁;
混淆的目的:
1、代碼混淆之后會隨機(jī)生成難易理解的類名榛臼、方法名以及屬性名伊佃,加大反編譯的難度;
2沛善、可以對apk進(jìn)行優(yōu)化航揉,縮小包的體積;
混淆的步驟:
1金刁、在gradle文件里面打開配置:minifyEnabled true帅涂;
2、在proguard-rules.pro 文件里面配置混淆規(guī)則尤蛮;
在配置混淆的時(shí)候媳友,需要注意:
1、四大組件以及view可以不進(jìn)行混淆产捞;
2醇锚、實(shí)體類不進(jìn)行混淆;
3、第三方庫根據(jù)各自的要求配置混淆規(guī)則焊唬;
4恋昼、自定義View不進(jìn)行混淆
4.引入wall插件, 一鍵打渠道包, 按渠道上線.
四、 Dart基礎(chǔ)
1.沒有 「public」「private」等關(guān)鍵字赶促,默認(rèn)就是公開的液肌,私有變量使用 下劃線 _開頭;
2.在單線程中是以消息循環(huán)機(jī)制來運(yùn)行的,其中包含兩個任務(wù)隊(duì)列鸥滨,一個是“微任務(wù)隊(duì)列” microtask queue嗦哆,另一個叫做“事件隊(duì)列” event queue;
3.不存在多線程,提供了一個 類似于新線程爵赵,但是不共享內(nèi)存的獨(dú)立運(yùn)行的 worker - isolate吝秕;
五、 Flutter
1.StatefulWidget
生命周期:
initState():Widget 初始化當(dāng)前 State空幻,在當(dāng)前方法中是不能獲取到 Context 的,如想獲取容客,可以試試 Future.delayed()
didChangeDependencies():在 initState() 后調(diào)用秕铛,State對象依賴關(guān)系發(fā)生變化的時(shí)候也會調(diào)用
deactivate():當(dāng) State 被暫時(shí)從視圖樹中移除時(shí)會調(diào)用這個方法,頁面切換時(shí)也會調(diào)用該方法缩挑,和Android里的 onPause 差不多但两。
dispose():Widget 銷毀時(shí)調(diào)用。
didUpdateWidget:Widget 狀態(tài)發(fā)生變化的時(shí)候調(diào)用供置。
2.三大樹
Widget 僅用于存儲渲染所需要的信息谨湘。
RenderObject 負(fù)責(zé)管理布局、繪制等操作芥丧。
Element 才是這顆巨大的控件樹上的實(shí)體紧阔。