Jave部分
一躬存、多線程
? Join()? 線程加入壁肋,執(zhí)行此方法的線程優(yōu)先使用cpu
? Yeild()? 線程釋放資源使所有線程能有相等的機(jī)會(huì)使用cpu
? Sleep() 相當(dāng)于讓線程睡眠片任,交出CPU桃犬,讓CPU去執(zhí)行其他的任務(wù)(不會(huì)釋放鎖)。
Wait()方法會(huì)讓線程進(jìn)入阻塞狀態(tài)嚣镜,并且會(huì)釋放線程占有的鎖激挪,并交出CPU執(zhí)行權(quán)限辰狡。wait是要釋放對(duì)象鎖,進(jìn)入等待池垄分。既然是釋放對(duì)象鎖宛篇,那么肯定是先要獲得鎖。所以wait必須要寫在synchronized代碼塊中薄湿,否則會(huì)報(bào)異常叫倍。
notify方法,也需要寫在synchronized代碼塊中,調(diào)用對(duì)象的這兩個(gè)方法也需要先獲得該對(duì)象的鎖.notify,notifyAll, 喚醒等待該對(duì)象同步鎖的線程,并放入該對(duì)象的鎖池中.對(duì)象的鎖池中線程可以去競(jìng)爭(zhēng)得到對(duì)象鎖,然后開(kāi)始執(zhí)行.如果是通過(guò)notify來(lái)喚起的線程,那先進(jìn)入wait的線程會(huì)先被喚起來(lái),并非隨機(jī)喚醒;如果是通過(guò)nootifyAll喚起的線程,默認(rèn)情況是最后進(jìn)入的會(huì)先被喚起來(lái),即LIFO的策略;notify()或者notifyAll()調(diào)用時(shí)并不會(huì)真正釋放對(duì)象鎖, 必須等到synchronized方法或者語(yǔ)法塊執(zhí)行完才真正釋放鎖.
Interrupt() 處于阻塞狀態(tài)(wait sleep)的線程調(diào)用時(shí)會(huì)拋出異常(InterruptedException )
守護(hù)線程? 不會(huì)去實(shí)現(xiàn)系統(tǒng)的主要功能,主要用于監(jiān)控豺瘤、抓取系統(tǒng)資源明細(xì)和運(yùn)行狀態(tài)? ? 等操作吆倦,如垃圾回收線程setDeamon(true)? 在start方法前調(diào)用,守護(hù)線程中不要做
二坐求、Java中的String蚕泽,StringBuilder,StringBuffer三者的區(qū)別
String,StringBuilder以及StringBuffer這三個(gè)類之間有什么區(qū)別呢,自己從網(wǎng)上搜索了一些資料须妻,有所了解了之后在這里整理一下仔蝌,便于大家觀看,也便于加深自己學(xué)習(xí)過(guò)程中對(duì)這些知識(shí)點(diǎn)的記憶荒吏,如果哪里有誤敛惊,懇請(qǐng)指正〈赂 這三個(gè)類之間的區(qū)別主要是在兩個(gè)方面瞧挤,即運(yùn)行速度和線程安全這兩方面。首先說(shuō)運(yùn)行速度儡湾,或者說(shuō)是執(zhí)行速度皿伺,在這方面運(yùn)行速度快慢為:StringBuilder > StringBuffer > String? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String最慢的原因:String為字符串常量,而StringBuilder和StringBuffer均為字符串變量盒粮,即String對(duì)象一旦創(chuàng)建之后該對(duì)象是不可更改的,但后兩者的對(duì)象是變量奠滑,是可以更改的丹皱。以下面一段代碼為例:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1 String str="abc";2 System.out.println(str);3 str=str+"de";4 System.out.println(str);
如果運(yùn)行這段代碼會(huì)發(fā)現(xiàn)先輸出“abc”,然后又輸出“abcde”宋税,好像是str這個(gè)對(duì)象被更改了摊崭,其實(shí),這只是一種假象罷了杰赛,JVM對(duì)于這幾行代碼是這樣處理的呢簸,首先創(chuàng)建一個(gè)String對(duì)象str,并把“abc”賦值給str乏屯,然后在第三行中根时,其實(shí)JVM又創(chuàng)建了一個(gè)新的對(duì)象也名為str,然后再把原來(lái)的str的值和“de”加起來(lái)再賦值給新的str辰晕,而原來(lái)的str就會(huì)被JVM的垃圾回收機(jī)制(GC)給回收掉了蛤迎,所以,str實(shí)際上并沒(méi)有被更改含友,也就是前面說(shuō)的String對(duì)象一旦創(chuàng)建之后就不可更改了替裆。所以,Java中對(duì)String對(duì)象進(jìn)行的操作實(shí)際上是一個(gè)不斷創(chuàng)建新的對(duì)象并且將舊的對(duì)象回收的一個(gè)過(guò)程窘问,所以執(zhí)行速度很慢辆童。
而StringBuilder和StringBuffer的對(duì)象是變量,對(duì)變量進(jìn)行操作就是直接對(duì)該對(duì)象進(jìn)行更改惠赫,而不進(jìn)行創(chuàng)建和回收的操作把鉴,所以速度要比String快很多。
另外儿咱,有時(shí)候我們會(huì)這樣對(duì)字符串進(jìn)行賦值
1 String str="abc"+"de";2 StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");3 System.out.println(str);4 System.out.println(stringBuilder.toString());
這樣輸出結(jié)果也是“abcde”和“abcde”纸镊,但是String的速度卻比StringBuilder的反應(yīng)速度要快很多倍阐,這是因?yàn)榈?行中的操作和
String str="abcde";
是完全一樣的,所以會(huì)很快逗威,而如果寫成下面這種形式
1 String str1="abc";2 String str2="de";3 String str=str1+str2;
那么JVM就會(huì)像上面說(shuō)的那樣峰搪,不斷的創(chuàng)建、回收對(duì)象來(lái)進(jìn)行這個(gè)操作了凯旭。速度就會(huì)很慢概耻。
2. 再來(lái)說(shuō)線程安全
在線程安全上,StringBuilder是線程不安全的罐呼,而StringBuffer是線程安全的
如果一個(gè)StringBuffer對(duì)象在字符串緩沖區(qū)被多個(gè)線程使用時(shí)鞠柄,StringBuffer中很多方法可以帶有synchronized關(guān)鍵字,所以可以保證線程是安全的嫉柴,但StringBuilder的方法則沒(méi)有該關(guān)鍵字厌杜,所以不能保證線程安全,有可能會(huì)出現(xiàn)一些錯(cuò)誤的操作计螺。所以如果要進(jìn)行的操作是多線程的夯尽,那么就要使用StringBuffer,但是在單線程的情況下登馒,還是建議使用速度比較快的StringBuilder匙握。
3. 總結(jié)一下
String:適用于少量的字符串操作的情況
StringBuilder:適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況
StringBuffer:適用多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況
三、Hashmap 和hashtable的區(qū)別?
1.Hashmap底層數(shù)組+鏈表實(shí)現(xiàn)陈轿,可以存儲(chǔ)null鍵和null值圈纺,線程不安全,初始size為16麦射,擴(kuò)容:newsize = oldsize*2蛾娶,size一定為2的n次冪
擴(kuò)容針對(duì)整個(gè)Map,每次擴(kuò)容時(shí)潜秋,原來(lái)數(shù)組中的元素依次重新計(jì)算存放位置茫叭,并重新插入,插入元素后才判斷該不該擴(kuò)容半等,有可能無(wú)效擴(kuò)容(插入后如果擴(kuò)容揍愁,如果沒(méi)有再次插入,就會(huì)產(chǎn)生無(wú)效擴(kuò)容)杀饵,當(dāng)Map中元素總數(shù)超過(guò)Entry數(shù)組的75%莽囤,觸發(fā)擴(kuò)容操作,為了減少鏈表長(zhǎng)度切距,元素分配更均勻朽缎,計(jì)算index方法:index = hash & (tab.length – 1)
2.hashtable底層數(shù)組+鏈表實(shí)現(xiàn),無(wú)論key還是value都不能為null,線程安全话肖,實(shí)現(xiàn)線程安全的方式是在修改數(shù)據(jù)時(shí)鎖住整個(gè)HashTable北秽,效率低,ConcurrentHashMap做了相關(guān)優(yōu)化最筒,初始size為11贺氓,擴(kuò)容:newsize = olesize*2+1,計(jì)算index的方法:index = (hash & 0x7FFFFFFF) % tab.length
四床蜘、java中接口和抽象類的區(qū)別
默認(rèn)的方法實(shí)現(xiàn)? 它可以有默認(rèn)的方法實(shí)現(xiàn)? 接口完全是抽象的辙培。它根本不存在方法的實(shí)現(xiàn)
實(shí)現(xiàn)? 子類使用extends關(guān)鍵字來(lái)繼承抽象類。如果子類不是抽象類的話邢锯,它需要提供抽象類中所有聲明的方法的實(shí)現(xiàn)扬蕊。? 子類使用關(guān)鍵字implements來(lái)實(shí)現(xiàn)接口。它需要提供接口中所有聲明的方法的實(shí)現(xiàn)
構(gòu)造器? 抽象類可以有構(gòu)造器? 接口不能有構(gòu)造器
與正常Java類的區(qū)別? 除了你不能實(shí)例化抽象類之外丹擎,它和普通Java類沒(méi)有任何區(qū)別? 接口是完全不同的類型
訪問(wèn)修飾符? 抽象方法可以有public尾抑、protected和default這些修飾符? 接口方法默認(rèn)修飾符是public。你不可以使用其它修飾符蒂培。
main方法? 抽象方法可以有main方法并且我們可以運(yùn)行它? 接口沒(méi)有main方法再愈,因此我們不能運(yùn)行它。
多繼承? 抽象方法可以繼承一個(gè)類和實(shí)現(xiàn)多個(gè)接口? 接口只可以繼承一個(gè)或多個(gè)其它接口
速度? 它比接口速度要快? 接口是稍微有點(diǎn)慢的毁渗,因?yàn)樗枰獣r(shí)間去尋找在類中實(shí)現(xiàn)的方法。
添加新方法? 如果你往抽象類中添加新的方法单刁,你可以給它提供默認(rèn)的實(shí)現(xiàn)灸异。因此你不需要改變你現(xiàn)在的代碼。? 如果你往接口中添加方法羔飞,那么你必須改變實(shí)現(xiàn)該接口的類肺樟。
五、java中的內(nèi)部類
? 1 分類:成員內(nèi)部類逻淌,局部?jī)?nèi)部類(不能有權(quán)限訪問(wèn)修飾符)么伯,匿名內(nèi)部類,靜態(tài)內(nèi)部類
? 2 為什么要用內(nèi)部類卡儒?隱式包含外部類對(duì)象并且能夠與之通信的特點(diǎn)田柔,完美的解決了多重繼承的問(wèn)題。
六骨望、Synchronize 和volatile
1.volatile 本質(zhì)是告訴jvm 該變量在寄存器上是不確定的硬爆,需要從主存中讀取當(dāng)前變量。Synchronize 則是鎖定當(dāng)前變量擎鸠,只有持有改鎖的線程可以訪問(wèn)缀磕。
2.volatile僅能使用在變量級(jí)別,synchronize可使用在變量方法級(jí)別
3.volatile僅能實(shí)現(xiàn)變量的修改可見(jiàn)性,而synchronize則可以保證變量修改可見(jiàn)性和原子性
注: 共享變量:如果一個(gè)變量在多個(gè)線程中都使用到了袜蚕,那么這個(gè)變量就是這幾個(gè)線程的共享變量糟把。
可見(jiàn)性:一個(gè)線程對(duì)共享變量的修改,能夠及時(shí)地到主內(nèi)存并且讓其他的線程看到牲剃。
Synchronize 可見(jiàn)性實(shí)現(xiàn):線程解鎖前會(huì)把共享變量的值更新到工作內(nèi)存的遣疯;線程加縮時(shí)會(huì)把工作內(nèi)存的共享變量值清空,從主內(nèi)存中獲取
Volatile 可見(jiàn)性實(shí)現(xiàn):通過(guò)內(nèi)存屏障颠黎,即當(dāng)對(duì)共享變量進(jìn)行操作后另锋,加入一條store屏障指令,使其值強(qiáng)制更新到主內(nèi)存狭归;對(duì)共享變量進(jìn)行操作前夭坪,加入一條load屏障指令,強(qiáng)制將主內(nèi)存中的值刷新到工作內(nèi)存过椎。?
七室梅、Throw 和throws
1.throw 用在方法體中,throws用于方法頭中
2.throws表示出現(xiàn)異常的一種可能性疚宇,并不一定會(huì)發(fā)生這些異常亡鼠;throw則是拋出了異常,執(zhí)行throw則一定拋出了某種異常對(duì)象敷待。
八间涵、java內(nèi)存模型
1.程序計(jì)數(shù)器、虛擬機(jī)棧榜揖、本地方法棧勾哩、堆、方法區(qū)举哟。
2.按照對(duì)象存儲(chǔ)時(shí)間的不同思劳,堆中的內(nèi)存可以劃分為新生代(Young)和老年代(Old),其中新生代又被劃分為 Eden 和 Survivor 區(qū)
3.不同的區(qū)域存放具有不同生命周期的對(duì)象妨猩。這樣可以根據(jù)不同的區(qū)域使用不同的垃圾回收算法潜叛,從而更具有針對(duì)性,進(jìn)而提高垃圾回收效率壶硅。
4.方法區(qū)主要是存儲(chǔ)已經(jīng)被 JVM 加載的類信息(版本威兜、字段、方法庐椒、接口)牡属、常量、靜態(tài)變量扼睬、即時(shí)編譯器編譯后的代碼和數(shù)據(jù)逮栅。
九悴势、TCP與UDP:
1、TCP面向連接(如打電話要先撥號(hào)建立連接);UDP是無(wú)連接的措伐,即發(fā)送數(shù)據(jù)之前不需要建立連接
2特纤、TCP提供可靠的服務(wù)。也就是說(shuō)侥加,通過(guò)TCP連接傳送的數(shù)據(jù)捧存,無(wú)差錯(cuò),不丟失担败,不重復(fù)昔穴,且按序到達(dá);UDP盡最大努力交付,即不保證可靠交付
3提前、TCP面向字節(jié)流吗货,實(shí)際上是TCP把數(shù)據(jù)看成一連串無(wú)結(jié)構(gòu)的字節(jié)流;UDP是面向報(bào)文的
4、TCP的三次握手過(guò)程:主機(jī)A向B發(fā)送連接請(qǐng)求狈网;主機(jī)B對(duì)收到的主機(jī)A的報(bào)文段進(jìn)行確認(rèn)宙搬;主機(jī)A再次對(duì)主機(jī)B的確認(rèn)進(jìn)行確認(rèn)。
UDP沒(méi)有擁塞控制拓哺,因此網(wǎng)絡(luò)出現(xiàn)擁塞不會(huì)使源主機(jī)的發(fā)送速率降低(對(duì)實(shí)時(shí)應(yīng)用很有用勇垛,如IP電話,實(shí)時(shí)視頻會(huì)議等)
4士鸥、每一條TCP連接只能是點(diǎn)到點(diǎn)的;UDP支持一對(duì)一闲孤,一對(duì)多,多對(duì)一和多對(duì)多的交互通信
5烤礁、TCP首部開(kāi)銷20字節(jié);UDP的首部開(kāi)銷小讼积,只有8個(gè)字節(jié)
6、TCP的邏輯通信信道是全雙工的可靠信道鸽凶,UDP則是不可靠信道
十币砂、HTTP與HTTPS的區(qū)別以及如何實(shí)現(xiàn)安全性
兩者的區(qū)別:
(1)建峭、HTTP是明文傳輸玻侥,傳輸內(nèi)容容易被篡改或者被竊取亿蒸;HTTPS是密文傳輸凑兰,https相當(dāng)于包裝了SSL\TLS協(xié)議的HTTP。
(2)边锁、https在網(wǎng)絡(luò)請(qǐng)求效率上會(huì)低于http姑食,因?yàn)椴捎昧瞬煌恼?qǐng)求協(xié)議以及更復(fù)雜的安全驗(yàn)證操作。
(3)茅坛、https需要申請(qǐng)CA證書音半,用于驗(yàn)證公鑰這個(gè)證書收費(fèi)则拷,HTTP不用。
主要通過(guò)非對(duì)稱加密+對(duì)稱加密+CA證書來(lái)保證請(qǐng)求安全的曹鸠。
十二煌茬、垃圾回收算法
1.所謂垃圾就是內(nèi)存中已經(jīng)沒(méi)有用的對(duì)象。 既然是”垃圾回收"彻桃,那就必須知道哪些對(duì)象是垃圾坛善。Java 虛擬機(jī)中使用一種叫作"可達(dá)性分析”的算法來(lái)決定對(duì)象是否可以被回收。
2.JVM 把內(nèi)存中所有的對(duì)象之間的引用關(guān)系看作一張圖邻眷,通過(guò)一組名為”GC Root"的對(duì)象作為起始點(diǎn)眠屎,從這些節(jié)點(diǎn)開(kāi)始向下搜索,搜索所走過(guò)的路徑稱為引用鏈肆饶,最后通過(guò)判斷對(duì)象的引用鏈?zhǔn)欠窨蛇_(dá)來(lái)決定對(duì)象是否可以被回收改衩。
方法區(qū)中靜態(tài)引用指向的對(duì)象。
仍處于存活狀態(tài)中的線程對(duì)象抖拴。
Native 方法中 JNI 引用的對(duì)象燎字。
十三、ArryList和linkedList
1.對(duì)ArrayList和LinkedList而言阿宅,在列表末尾增加一個(gè)元素所花的開(kāi)銷都是固定的候衍。對(duì)ArrayList而言,主要是在內(nèi)部數(shù)組中增加一項(xiàng)洒放,指向所添加的元素蛉鹿,偶爾可能會(huì)導(dǎo)致對(duì)數(shù)組重新進(jìn)行分配;而對(duì)LinkedList而言往湿,這個(gè)開(kāi)銷是統(tǒng)一的妖异,分配一個(gè)內(nèi)部Entry對(duì)象。
2.在ArrayList的中間插入或刪除一個(gè)元素意味著這個(gè)列表中剩余的元素都會(huì)被移動(dòng)领追;而在LinkedList的中間插入或刪除一個(gè)元素的開(kāi)銷是固定的他膳。
3.LinkedList不支持高效的隨機(jī)元素訪問(wèn)。
4.ArrayList的空間浪費(fèi)主要體現(xiàn)在在list列表的結(jié)尾預(yù)留一定的容量空間绒窑,而LinkedList的空間花費(fèi)則體現(xiàn)在它的每一個(gè)元素都需要消耗相當(dāng)?shù)目臻g
十四棕孙、Atomic
用volatile關(guān)鍵字修飾value字段
AtomicInteger用value字段來(lái)存儲(chǔ)數(shù)據(jù)值,volatile關(guān)鍵字保證了value字段對(duì)各個(gè)線程的可見(jiàn)性些膨。各線程讀取value字段時(shí)蟀俊,會(huì)先從主內(nèi)存把數(shù)據(jù)同步到工作內(nèi)存,這樣保證可見(jiàn)性订雾。
Unsafe實(shí)現(xiàn)操作原子性肢预,用戶在使用時(shí)無(wú)需額外的同步操作。
如AtomicInteger提供了自增方法getAndIncrement洼哎,其內(nèi)部實(shí)現(xiàn)是由Unsafe類的compareAndSetInt方法來(lái)保證的烫映。
十五沼本、樂(lè)觀鎖和悲觀鎖
悲觀鎖:線程一旦得到鎖,其他線程就掛起等待锭沟,適用于寫入操作頻繁的場(chǎng)景擅威;synchronized 就是悲觀鎖
樂(lè)觀鎖:假設(shè)沒(méi)有沖突,不加鎖冈钦,更新數(shù)據(jù)時(shí)判斷該數(shù)據(jù)是否過(guò)期郊丛,過(guò)期的話則不進(jìn)行數(shù)據(jù)更新,適用于讀取操作頻繁的場(chǎng)景
樂(lè)觀鎖 CAS:Compare And Swap瞧筛,更新數(shù)據(jù)時(shí)先比較原值是否相等厉熟,不相等則表示數(shù)據(jù)過(guò)去,不進(jìn)行數(shù)據(jù)更新
樂(lè)觀鎖實(shí)現(xiàn):AtomicInteger较幌、AtomicLong揍瑟、AtomicBoolean
Android 部分
一、自定義view
? 三個(gè)方法:繪制乍炉,測(cè)量绢片,放置。繪制(Android除了游戲用opengl繪制其余基本都是Canvas實(shí)現(xiàn)的)
1岛琼、繪制對(duì)象:
?弧線(arcs) canvas.
填充顏色(argb和color)
Bitmap
圓(circle和oval)
點(diǎn)(point)
線(line)
矩形(Rect)
圖片(Picture)
圓角矩形 (RoundRect)
文本(text)
頂點(diǎn)(Vertices)
路徑(path)
2底循、幾何變換
在使用Canvas的save和restore方法時(shí),基本上都是伴隨著我們需要對(duì)Canvas進(jìn)行平移或者旋轉(zhuǎn)操作
在代碼中首先在(40,40)的位置繪制了一個(gè)半徑為40的圓槐瑞,這里的數(shù)字表示的都是像素熙涤,在繪制完成會(huì),我們保存當(dāng)前的canvas狀態(tài)困檩,在這里我就理解為復(fù)制了一個(gè)canvas祠挫,并將這個(gè)canvas向右移動(dòng)mWidth/2,這時(shí)悼沿,canvas的坐標(biāo)的原點(diǎn)已經(jīng)發(fā)生改變了 這時(shí)在執(zhí)行繪制動(dòng)作等舔,在(0,40)繪制一個(gè)圓,然后調(diào)用Canvas的restore方法糟趾,相當(dāng)于將新復(fù)制的canvas上的內(nèi)容與原來(lái)的canvas的內(nèi)容進(jìn)行合并慌植,這個(gè)合并根據(jù)屏幕的坐標(biāo)進(jìn)行的(個(gè)人是這么理解的),在調(diào)用restore方法后拉讯,新復(fù)制的canvas就被銷毀了涤浇,而原來(lái)的canvas的坐標(biāo)還是以左上角為原點(diǎn)的坐標(biāo)系鳖藕。
3魔慷、onmessure()方法什么時(shí)候被調(diào)。
? 當(dāng)執(zhí)行setText(),addview(),setvisiblity()方法的時(shí)候會(huì)調(diào)用View的onmessure()方法
因?yàn)檎{(diào)用 addView著恩、setVisbility院尔、setTextView等都會(huì)調(diào)用 requestLayout蜻展,而調(diào)用 requestLayout就會(huì)執(zhí)行 view的 繪制流程,也就是說(shuō)會(huì)執(zhí)行 performMeasure邀摆、performLayout纵顾、performDraw,就會(huì)執(zhí)行 onMeasure栋盹;
為了防止卡頓施逾、提高性能和效率,要慎用 addView例获、setVisbility汉额、setTextView等方法,因?yàn)檫@幾個(gè)方法會(huì)重新調(diào)用 requestLayout榨汤,會(huì)重新測(cè)量蠕搜、重新擺放、重新繪制view收壕,影響性能妓灌;
二、硬件加速
對(duì)于 Android 來(lái)說(shuō)蜜宪,硬件加速有它專屬的意思:在 Android 里虫埂,硬件加速專指把 View 中繪制的計(jì)算工作交給 GPU 來(lái)處理。
在Android中圃验,可以四給不同層次上開(kāi)啟硬件加速:
? 1.應(yīng)用:
<application android:hardwareAccelerated="true">
? 2.Activity
<activity android:hardwareAccelerated="true">
? 3.Window
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
? 4.View
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
? 在這四個(gè)層次中告丢,應(yīng)用和Activity是可以選擇的,Window只能打開(kāi)损谦,View只能關(guān)閉岖免。
我們需要看看哪些屬性是不支持硬件加速的
三、activity生命周期
1照捡、A 中打開(kāi)B
A onPause()---> B onCreate() ---->B onStart() ---> B o'nResume() ---> A onstop()
再點(diǎn)返回A的生命周期函數(shù)調(diào)用
B onPause() --->A onRestart() ---> A onStart() --->A onResume() ---> B onStop ---> B onDestroy()
2颅湘、A 中打開(kāi)B如果B是透明的activity,則不會(huì)執(zhí)行a的onstop的restart以及start方法(通dialog)
A onPause()---> B onCreate() ---->B onStart() ---> B o'nResume()?
再點(diǎn)返回A的生命周期函數(shù)調(diào)用
B onPause() --->A onResume() ---> B onStop ---> B onDestroy()
四栗精、Android 布局優(yōu)化
Include 提高布局的復(fù)用闯参,
Merge 用于降低view樹(shù)的層級(jí)
主要應(yīng)用場(chǎng)景: 1.布局頂節(jié)點(diǎn)是fragmLayout且不需要設(shè)置padding和backgroud,可以用merge代替悲立,Activity的內(nèi)容視圖的 parentview是Fragmenlayout鹿寨,所以可以用merge消除
2.某布局用于子布局被include時(shí)使用merge當(dāng)作該布局的頂節(jié)點(diǎn),這樣在被引入時(shí)頂結(jié)點(diǎn)會(huì)自動(dòng)被忽略薪夕, 而將其子節(jié)點(diǎn)全部合并到主布局中脚草。
3.由于無(wú)論布局文件的根節(jié)點(diǎn)是什么系統(tǒng)都會(huì)在上一層生成一個(gè)<FramLayout>標(biāo)簽,因此原献,在布局文件 的根節(jié)點(diǎn)上使用<FramLayout>是多余的但xml文件不能沒(méi)有根節(jié)點(diǎn) 馏慨,因此可以使用<merge>代替<FramLayout>埂淮,系統(tǒng)在編譯時(shí)不會(huì)為<merge>生成任何節(jié)點(diǎn),相當(dāng)于一個(gè)xml文件的節(jié)點(diǎn)占位符<merge>的意思其實(shí)就是合并兩個(gè)<FramLayout>写隶,所以使用<merge>代替<FramLayout>可以大大減少<FramLayout>的生成;
ViewStub 實(shí)際上時(shí)一個(gè)寬高均為0的view 通過(guò)延遲加載的布局的方式優(yōu)化布局提升渲染性能.當(dāng)初次渲染布局文件時(shí), ViewStub 控件雖然也占據(jù)內(nèi)存, 但是相比于其他控件, 它所占內(nèi)存很小. 它主要是作為一個(gè)“占位符”, 放置于 View Tree中, 且它本身是不可見(jiàn)的.
五倔撞、android 代理模式?
1、靜態(tài)代理的特點(diǎn) :一個(gè)代理只服務(wù)于一類對(duì)象
優(yōu)點(diǎn):協(xié)調(diào)了調(diào)用者和被調(diào)用者慕趴,降低了耦合性痪蝇,代理對(duì)象作為客戶對(duì)象和目標(biāo)對(duì)象的中,起到了對(duì)目標(biāo)對(duì)象的保護(hù)作用
缺點(diǎn):在客戶和目標(biāo)中增加了代理對(duì)象冕房,使得處理速度變慢霹俺,代理需要做額外的工作增加了系統(tǒng)的復(fù)雜度
2、動(dòng)態(tài)代理:相比于靜態(tài)代理直接調(diào)用目標(biāo)對(duì)象的方法毒费,動(dòng)態(tài)代理利用反射機(jī)制來(lái)調(diào)用目標(biāo)對(duì)象得方法丙唧,動(dòng)態(tài)代理創(chuàng)建時(shí)可傳入非指定類型的對(duì)象,因此可以代理多類對(duì)象觅玻,提高了代碼的重用性
3想际、插件化打開(kāi)apk
插件化的優(yōu)勢(shì):宿主和插件分開(kāi)編譯,并行開(kāi)發(fā)溪厘,動(dòng)態(tài)更新插件胡本,按需要下載插件
實(shí)現(xiàn):? 1.宿主應(yīng)用中代理activity建立,activity中加載布局生命周期等方法要調(diào)用到你要打開(kāi)的(未安裝的apk中的)activity
? 2.傳入未安裝activity的路徑畸悬,建立classloader
六侧甫、Android 中的parcelable 和java中的serializable
1.定義 序列化事對(duì)象轉(zhuǎn)為字節(jié)序列的過(guò)程 反序列化字節(jié)序列轉(zhuǎn)為對(duì)象的過(guò)程
2.在開(kāi)發(fā)中我們經(jīng)常會(huì)遇到這樣的問(wèn)題,activity或者fragment傳值的時(shí)候一般做法時(shí)用intent或者bundle中蹋宦,或者需要將一些對(duì)象數(shù)據(jù)存在本地披粟,這時(shí)候如果對(duì)象沒(méi)有實(shí)現(xiàn)parcelable或者serilizable,就無(wú)法完成上述操作冷冗,那么這兩者為我們做了什么呢守屉?簡(jiǎn)單的說(shuō)將對(duì)象轉(zhuǎn)化可傳輸?shù)亩M(jìn)制流(二進(jìn)制序列)的過(guò)程我們稱之為序列化,我們可以通過(guò)序列化(對(duì)象轉(zhuǎn)化為可傳輸二進(jìn)制流或者序列)以及反序列化(二進(jìn)制流或者序列轉(zhuǎn)化為對(duì)象)實(shí)現(xiàn)對(duì)象的網(wǎng)絡(luò)傳輸或進(jìn)程傳輸以及存儲(chǔ)蒿辙!
3.Parcelable和Serializable的區(qū)別和比較
Parcelable和Serializable都是實(shí)現(xiàn)序列化并且都可以用于Intent間傳遞數(shù)據(jù),Serializable是Java的實(shí)現(xiàn)方式,可能會(huì)頻繁的IO操作,所以消耗比較大,但是實(shí)現(xiàn)方式簡(jiǎn)單 Parcelable是Android提供的方式,效率比較高,但是實(shí)現(xiàn)起來(lái)復(fù)雜一些 , 二者的選取規(guī)則是:內(nèi)存序列化上選擇Parcelable, 存儲(chǔ)到設(shè)備或者網(wǎng)絡(luò)傳輸上選擇Serializable(當(dāng)然Parcelable也可以但是稍顯復(fù)雜)
選擇序列化方法的原則
1)在使用內(nèi)存的時(shí)候拇泛,Parcelable比Serializable性能高,所以推薦使用Parcelable思灌。
2)Serializable在序列化的時(shí)候會(huì)產(chǎn)生大量的臨時(shí)變量俺叭,從而引起頻繁的GC,如果是僅僅在內(nèi)存中使用泰偿,比如activity熄守、service之間進(jìn)行對(duì)象的傳遞,強(qiáng)烈推薦使用Parcelable。
3)Parcelable不能使用在要將數(shù)據(jù)存儲(chǔ)在磁盤上的情況柠横,因?yàn)镻arcelable不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況下。盡管Serializable效率低點(diǎn)课兄,但此時(shí)還是建議使用Serializable 牍氛。
七、getheight() 和getMeasureHeight()有什么區(qū)別
getMeasureHeight() 在messure()方法結(jié)束后能獲取到烟阐,而getHeight()需要在layout()執(zhí)行后能獲取到值搬俊;
getMeasureHeight()是通過(guò)setMeasureHeight()方法設(shè)置的值,而getheight()則是通過(guò)視圖的坐標(biāo)點(diǎn)作差得到的
八蜒茄、apk的打包流程和安裝流程
? 打包:1. appt工具打包資源文件生成R.java文件唉擂;
? ? ? ? 2.aidl工具處理處理AIDL文件生成對(duì)應(yīng)java文件
? 3.javac 編譯java文件生成.class文件
? 4.把.class文件轉(zhuǎn)化為davik支持的的.dex文件
? 5.javasinger對(duì)未簽名apk僅從簽名
? 6.zipalign對(duì)文件進(jìn)行對(duì)齊處理
九、SurfaceView檀葛、TextureView玩祟、SurfaceTexture、GLSurfaceView
SurfaceView:使用雙緩沖機(jī)制屿聋,有自己的 surface空扎,在一個(gè)獨(dú)立的線程里繪制,Android7.0之前不能平移润讥、縮放
TextureView:持有 SurfaceTexture转锈,將圖像處理為 OpenGL 紋理更新到 HardwareLayer,必須開(kāi)啟硬件加速楚殿,Android5.0之前在主線程渲染撮慨,之后有獨(dú)立的渲染線程,可以平移脆粥、旋轉(zhuǎn)砌溺、縮放
SurfaceTexture:將圖像流轉(zhuǎn)為 OpenGL 外部紋理,不直接顯示
GLSurfaceView:加入 EGL 管理变隔,自帶 GL 上下文和 GL 渲染線程
十抚吠、binder傳遞數(shù)據(jù)
內(nèi)核剛開(kāi)始只是分配了一個(gè)物理頁(yè),并且分別將這個(gè)物理頁(yè)映射到進(jìn)程的內(nèi)核虛擬地址空間V1(修改內(nèi)核空間的頁(yè)表映射)和進(jìn)程的用戶虛擬地址空間V2(修改用戶空間的頁(yè)表映射)弟胀。在用戶空間訪問(wèn)V1和在內(nèi)核空間訪問(wèn)V2楷力,其實(shí)都是訪問(wèn)的是同一個(gè)物理內(nèi)存塊,從而實(shí)現(xiàn)進(jìn)程的內(nèi)核和用戶空間共享同一塊物理內(nèi)存的目的孵户。這樣binder驅(qū)動(dòng)在內(nèi)核空間萧朝,將一段數(shù)據(jù)拷貝到這個(gè)物理頁(yè),則該進(jìn)程的用戶空間則不需要copy_to_user()即可以同步看到內(nèi)核空間的修改夏哭,并能夠訪問(wèn)這段物理內(nèi)存
ProcessState 對(duì)應(yīng)于一個(gè)進(jìn)程检柬,是進(jìn)程內(nèi)單例,而 IPCThreadState 對(duì)應(yīng)于一個(gè)線程,是線程單例(Thread Local)何址。ProcessState 中打開(kāi)了 binder 驅(qū)動(dòng)里逆、進(jìn)行 mmap 映射,雖然調(diào)用了 ioctl() 函數(shù)用爪,但主要是一些初始化配置原押。而具體的 BR_TRANSACTION 等命令都是由 IPCThreadState 負(fù)責(zé)執(zhí)行的,當(dāng)上層傳來(lái)一個(gè)命令偎血,會(huì)調(diào)用它的 transact 函數(shù)
ProcessState 的構(gòu)造函數(shù)初始化了一些重要的變量诸衔,包括調(diào)用 open_driver() 打開(kāi) binder 設(shè)備,初始化 binder 線程最大數(shù)量颇玷,將 BINDER_VM_SIZE (接近 1M ) 的內(nèi)存與 binder 驅(qū)動(dòng) mmap.
除了 ProcessState 的初始化笨农,ProcessState 中還有一些比較重要的方法,比如 getStrongProxyForHandle()帖渠、getWeakProxyForHandle() 等谒亦,可以通過(guò) handle 值獲取對(duì)應(yīng) IBinder 對(duì)象
十一、IntentService
IntentService 是繼承于 Service 并處理異步請(qǐng)求的一個(gè)類空郊,在 IntentService 內(nèi)有一個(gè)工作線程來(lái)處理耗時(shí)操作诊霹,啟動(dòng) IntentService 的方式和啟動(dòng)傳統(tǒng) Service 一樣,同時(shí)渣淳,當(dāng)任務(wù)執(zhí)行完后脾还,IntentService 會(huì)自動(dòng)停止,而不需要我們?nèi)ナ謩?dòng)控制入愧。另外鄙漏,可以啟動(dòng) IntentService 多次,而每一個(gè)耗時(shí)操作會(huì)以工作隊(duì)列的方式在IntentService 的 onHandleIntent 回調(diào)方法中執(zhí)行棺蛛,并且怔蚌,每次只會(huì)執(zhí)行一個(gè)工作線程,執(zhí)行完第一個(gè)再執(zhí)行第二個(gè)旁赊,以此類推桦踊。
十二、Fragment
1终畅、FragmnetPageAdapter在切換頁(yè)面時(shí)籍胯,只是將Fragment進(jìn)行分離,適合頁(yè)面較少的Fragment使用以保存一些內(nèi)存离福,對(duì)系統(tǒng)內(nèi)存影響不大杖狼。
2、FragmentPageStateAdapter在每次切換頁(yè)面的時(shí)候妖爷,是將Fragment進(jìn)行回收蝶涩,適合頁(yè)面較多的Fragment使用,這樣就不會(huì)消耗更多的內(nèi)存
3、commit/commitAllowingStateLoss兩者都可以提交fragment的操作绿聘,唯一的不同是第二種方法嗽上,允許丟失一些界面的狀態(tài)和信息,幾乎所有的開(kāi)發(fā)者都遇到過(guò)這樣的錯(cuò)誤:無(wú)法在activity調(diào)用了onSaveInstanceState之后再執(zhí)行commit()熄攘,這種異常時(shí)可以理解的兽愤,界面被系統(tǒng)回收(界面已經(jīng)不存在),為了在下次打開(kāi)的時(shí)候恢復(fù)原來(lái)的樣子鲜屏,系統(tǒng)為我們保存界面的所有狀態(tài)烹看,這個(gè)時(shí)候我們?cè)偃バ薷慕缑胬碚撋峡隙ㄊ遣辉试S的国拇,所以為了避免這種異常洛史,要使用第二種方法。
4酱吝、add/replace ?add方式來(lái)進(jìn)行show和add也殖,這種方式你切換fragment不會(huì)讓fragment重新刷新,只會(huì)調(diào)用onHiddenChanged(boolean isHidden)务热。而用replace方式會(huì)使fragment重新刷新忆嗜,因?yàn)閍dd方式是將fragment隱藏了而不是銷毀再創(chuàng)建,replace方式每次都是重新創(chuàng)建崎岂。