Dalvik和Sun JVM
共同點(diǎn)
- 都是解釋執(zhí)行
byte code
(字節(jié)碼) - 都是每個(gè) OS 進(jìn)程運(yùn)行一個(gè)
VM
僵井,并執(zhí)行一個(gè)單獨(dú)的程序 - 在較新版本中(
Froyo / Sun JDK 1.5
)都實(shí)現(xiàn)了相當(dāng)程度的JIT compiler
(即時(shí)編譯) 用于提速
不同點(diǎn)
-
dvm
執(zhí)行的是.dex
格式文件陕截,jvm
執(zhí)行的是.class
文件,android
程序編譯完之后生產(chǎn).class
文件批什,然后农曲,dex
工具會(huì)把.class
文件處理成.dex
文件,然后把資源文件
和.dex
文件等打包成.apk
文件驻债。apk
就是android package的意思乳规。
jvm執(zhí)行的是.class
文件。 -
dvm
是基于寄存器
的虛擬機(jī) 而jvm
執(zhí)行是基于虛擬棧
的虛擬機(jī)合呐。寄存器存取速度比椖旱模快的多
,dvm可以根據(jù)硬件實(shí)現(xiàn)最大的優(yōu)化淌实,比較適合移動(dòng)設(shè)備冻辩。 -
.class
文件存在很多的冗余信息,dex
工具會(huì)去除冗余信息拆祈,并把所有的.class
文件整合到.dex
文件中恨闪。減少了I/O
操作,提高了類的查找速度缘屹。
IPC進(jìn)程間通信
在一個(gè)應(yīng)用中存在多個(gè)進(jìn)程的情況(不討論兩個(gè)應(yīng)用之間的多進(jìn)程情況)凛剥,開啟多進(jìn)程:在Android
的manifests
文件中指定android:process屬性
,除此之外沒有其他辦法
轻姿。
進(jìn)程名:以“:“開頭的進(jìn)程屬于當(dāng)前應(yīng)用的私有進(jìn)程犁珠,其他的應(yīng)用不可以和它跑在同一個(gè)進(jìn)程中
,而進(jìn)程名不以”:“開頭的屬于全局進(jìn)程
互亮,其他應(yīng)用通過shareUID
方式可以和它跑在同一個(gè)進(jìn)程中犁享。Android給每一個(gè)進(jìn)程都分配一個(gè)獨(dú)立的虛擬機(jī),所以運(yùn)行在不同進(jìn)程中的四大組件豹休,只要他們之間需要通過內(nèi)存來共享數(shù)據(jù)炊昆,都會(huì)共享失敗,這也是多進(jìn)程所帶來的主要影響。
使用多進(jìn)程會(huì)造成問題:
- 靜態(tài)成員和單例模式完全失效
- 線程同步機(jī)制完全失效
-
SharedPreferences
的可靠性下降 -
Application
會(huì)多次創(chuàng)建
SharedPreferences
的可靠性降低凤巨,因?yàn)?SharedPrefrences不支持兩個(gè)進(jìn)程同時(shí)執(zhí)行寫操作视乐,可能會(huì)導(dǎo)致一定幾率的數(shù)據(jù)丟失,這是因?yàn)?code>sharedPrefrences底層是通過讀寫xml
實(shí)現(xiàn)的敢茁。
實(shí)現(xiàn)跨進(jìn)程通信的方式:
- 通過Intent來傳遞數(shù)據(jù)(通過Bundle來綁定數(shù)據(jù))
-
共享文件和
SharedPrefereneces
- 基于Binder的
Messenger
和AIDL
以及Socket
等
序列化:靜態(tài)成員變量屬于類不屬于對(duì)象佑淀,所以不會(huì)參與序列化過程,其次transient關(guān)鍵字標(biāo)記的成員變量不參與序列化過程彰檬。 實(shí)現(xiàn)了Parcelable
接口的類都是可以直接序列化的伸刃,Android中已經(jīng)實(shí)現(xiàn)了parcelable
類的有:Intent
,Bundle
逢倍, Bitmap
等捧颅,同時(shí) list
和 map
也可以序列化,前提是他們的每個(gè)元素都能序列化
较雕。實(shí)現(xiàn)了parcelable接口的類都可以通過Intent
和Binder
來傳遞碉哑。
Binder類:實(shí)現(xiàn)了IBinder接口,從IPC
角度來說郎笆,Binder
是Android
中一種垮進(jìn)程通信方式谭梗,還可以理解為一種虛擬的物理設(shè)備,該通信在Linux
中是沒有的宛蚓。Binder
是連接各種manager
(ActivityManager
, windowManager
)和相應(yīng)的ManagerService
的橋梁设塔。
binder驅(qū)動(dòng)
是整個(gè)流程的核心
-
Server
將自己的binder
通過binder驅(qū)動(dòng)
在SM
中進(jìn)行注冊凄吏。 -
binder驅(qū)動(dòng)
會(huì)建立一個(gè)binder實(shí)體
的數(shù)據(jù)節(jié)點(diǎn)和實(shí)體的引用。 -
Binder驅(qū)動(dòng)
再把名字和引用打包發(fā)給SM
闰蛔。 -
Client
通過binder驅(qū)動(dòng)
拿著他所需要的binder名字
向SM
請求binder
痕钢。 -
SM
在自己的查找表
里面找到對(duì)應(yīng)的引用之后再通過binder驅(qū)動(dòng)
返回給client
。
Intent傳遞數(shù)據(jù)
根據(jù)API文檔序六,
Intent/Bundle
支持傳遞基本類型
的數(shù)據(jù)和基本類型的數(shù)組
數(shù)據(jù)任连,以及String/CharSequence
。而對(duì)于其它類型的數(shù)據(jù)貌似無能為力例诀,其實(shí)不然随抠,我們可以在Intent/Bundle
的API中看到Intent/Bundle還可以傳遞 Parcelable(包裹化,郵包)和Serializable(序列化)類型的數(shù)據(jù)繁涂,以及它們的數(shù)組/列表數(shù)據(jù)拱她。
數(shù)據(jù)存儲(chǔ)
Android數(shù)據(jù)存儲(chǔ)方式:SharedPreferences
,SQLite
扔罪,ContentProvider
秉沼,File
。
SharedPreferences
鍵值對(duì)的形式存儲(chǔ),底層是xml
文件唬复。并且可以設(shè)置權(quán)限矗积,是否和其他應(yīng)用共享該項(xiàng)文件
。 File:Android
分為內(nèi)部存儲(chǔ)
和外部存儲(chǔ)
敞咧,內(nèi)部存儲(chǔ)中屬于APP私有棘捣,其他任何應(yīng)用都不能訪問,APP卸載時(shí)自動(dòng)刪除妄均。外部存儲(chǔ)
又分為兩類:公共文件
和私有文件
柱锹,私有文件:本屬于您的應(yīng)用且應(yīng)在用戶卸載您的應(yīng)用時(shí)刪除的文件。盡管這些文件在技術(shù)上可被用戶和其他應(yīng)用訪問(因?yàn)樗鼈冊谕獠看鎯?chǔ)上)丰包,它們是實(shí)際上不向您的應(yīng)用之外的用戶提供值的文件禁熏。當(dāng)用戶卸載您的應(yīng)用時(shí),系統(tǒng)會(huì)刪除應(yīng)用外部專用目錄中的所有文件邑彪。
Android動(dòng)畫
View動(dòng)畫
View動(dòng)畫
注意事項(xiàng):View動(dòng)畫執(zhí)行之后并未改變View的真實(shí)布局屬性值
瞧毙。切記這一點(diǎn),譬如我們在Activity
中有一 個(gè)Button
在屏幕上方寄症,我們設(shè)置了平移動(dòng)畫移動(dòng)到屏幕下方然后保持動(dòng)畫最后執(zhí)行狀態(tài)呆在屏幕下方宙彪,這時(shí)如果點(diǎn) 擊屏幕下方動(dòng)畫執(zhí)行之后的Button
是沒有任何反應(yīng)的,而點(diǎn)擊原來屏幕上方?jīng)]有Button
的地方卻響應(yīng)的是點(diǎn)擊Button
的事件有巧。
View
動(dòng)畫有四種變換效果释漆,對(duì)應(yīng)Animation
的四個(gè)子類:TranslateAnimation
(平移),ScaleAnimation
(縮放)篮迎,AlphaAnimation
(透明度動(dòng)畫)男图,RotateAnimation
(旋轉(zhuǎn)),一般采用XML的方式來定義動(dòng)畫甜橱,可讀性更好逊笆。
幀動(dòng)畫
對(duì)應(yīng)AnimationDrawale
來使用幀動(dòng)畫,通過XML
來定義個(gè)AnimationDrawable
岂傲,然后把xml
作為Drawable
作為view
的背景來播放動(dòng)畫就可以了难裆。
注意
幀動(dòng)畫使用比較簡單,比較容易引起OOM
镊掖,所以盡量避免使用過多尺寸較大的圖片
乃戈。
屬性動(dòng)畫
主要由ValueAnimator
,ObjectAnimator
和AnimatorSet
類實(shí)現(xiàn)堰乔。
Bitmap加載:
Bitmap
代表一張圖片偏化,BitmapFactory
提供了四類方法:decodeFile
,decodeResource
镐侯,decodeStream
和 decodeByteArray
加載bitmap
侦讨。
Retrofit優(yōu)點(diǎn)
- 采用
動(dòng)態(tài)代理機(jī)制
和反射
驶冒,使代碼寫起來特別簡單,看起來也很清晰韵卤。 - 可以配合
OkHttp攔截器
骗污,很方便的在header
加token
或者處理cookie
等等。 - 可配合
RxJava
沈条,可以讓多個(gè)接口調(diào)用組合變的更簡單需忿。
RequestLayout,invalidate和postInvalidate
-
requestLayout:當(dāng)
view
確定自身已經(jīng)不再適合現(xiàn)有的區(qū)域時(shí)蜡歹,該view
本身調(diào)用這個(gè)方法要求parent view
重新調(diào)用他的onMeasure
屋厘,onLayout
來對(duì)重新設(shè)置自己位置。
特別的當(dāng)view
的layoutparameter
發(fā)生改變月而,并且它的值還沒能應(yīng)用到view
上汗洒,這時(shí)候適合調(diào)用這個(gè)方法。 -
invalidate:
invalidate
內(nèi)部最終會(huì)調(diào)用到performTraversals
(視圖繪制的入口)父款,但由于沒有設(shè)置強(qiáng)制視圖重新測量的標(biāo)志位溢谤,所以只會(huì)執(zhí)行onDraw
方法。 -
postInvalidate:是在
非UI線程
使用憨攒。
Rxjava
一個(gè)詞:
異步
世杀。
RxJava
在GitHub
主頁上的自我介紹是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一個(gè)在Java VM
上使用可觀測的序列來組成異步的、基于事件的程序的庫)肝集。這就是RxJava
瞻坝,概括得非常精準(zhǔn)。
在RxJava
的默認(rèn)
規(guī)則中杏瞻,事件的發(fā)出和消費(fèi)都是在同一個(gè)線程
的湿镀。在不指定線程的情況下,RxJava
遵循的是線程不變的原則伐憾,即:在哪個(gè)線程調(diào)用subscribe()
,就在哪個(gè)線程生產(chǎn)事件赫模;在哪個(gè)線程生產(chǎn)事件树肃,就在哪個(gè)線程消費(fèi)事件。如果需要切換線程瀑罗,就需要用到Scheduler
(調(diào)度器)胸嘴。
RxJava
的異步實(shí)現(xiàn),是通過一種擴(kuò)展的觀察者模式
來實(shí)現(xiàn)的斩祭。
變換(map()
,flatmap()
):
Map
行為:
- 創(chuàng)建了一個(gè)新的
Observable
- 創(chuàng)建了一個(gè)新的
OnSubscribe
: 其中的call
方法是整個(gè)調(diào)用鏈的關(guān)鍵. 它調(diào)用了上一級(jí)Observable.onSubscribe.call
, 同時(shí), 還將結(jié)果通過transform
對(duì) ‘第一步’ 處理后的結(jié)果進(jìn)行變形劣像, 然后將變形后的結(jié)果再轉(zhuǎn)發(fā)給‘第三步’ 中subscribe(Subscriber…)
中的Subscriber
處理. 那我們馬上看一下 ‘第三步’。
Glide優(yōu)點(diǎn)
- 默認(rèn)
Bitmap
格式是RGB_565
摧玫,內(nèi)存占用更少
耳奕,原因在于Picasso是加載了全尺寸的圖片到內(nèi)存,然后讓GPU來實(shí)時(shí)重繪大小。而Glide加載的大小
和ImageView的大小是一致的
屋群,因此更小。 磁盤緩存
- Picasso和Glide在磁盤緩存策略上有很大的不同。Picasso緩存的是全尺寸的遭商,而
Glide緩存的是跟ImageView尺寸相同
宪巨。 -
Glide
可以加載GIF動(dòng)態(tài)圖
,而Picasso不能对竣。 - 除了gif動(dòng)畫之外庇楞,
Glide
還可以將任何的本地視頻解碼成一張靜態(tài)圖片。
Material Design
-
TextInputLayout
必須把EditText
包含起來否纬,不能單獨(dú)使用吕晌。
<android.support.design.widget.TextInputLayout
android:id="@+id/til_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.TextInputLayout>
-
FloatingActionButton
繼承自ImageView
。 -
NavigationView
實(shí)現(xiàn)DrawerLayout
導(dǎo)航菜單界面,通過
app:headerLayout="@layout/navigation_header"
app:menu="@menu/drawer_view"
來設(shè)置.
SQLite
public long insert (String table, String nullColumnHack, ContentValues values)
插入數(shù)據(jù)
參數(shù)介紹 :
- 參數(shù)①
table
: 數(shù)據(jù)庫中的表名, 要插入數(shù)據(jù)的表; - 參數(shù)②
nullColumnHack
: 該參數(shù)是可選的, 數(shù)據(jù)庫表中不允許插入一行空的數(shù)據(jù), 插入數(shù)據(jù)至少有一列不為null
才能插入, 如果后面的values
是null
, 并且不知道列的名稱, 那么插入操作會(huì)失敗, 為了避免這種情況, 就出現(xiàn)了本參數(shù), 為了防止values
為null
的情況; - 參數(shù)③
ContentValues
: 相當(dāng)于一個(gè)Map
集合烦味,鍵是列名聂使,值是對(duì)應(yīng)列名要插入的數(shù)據(jù);
插入原則 : 不管第三個(gè) ContentValues
參數(shù)是否為null
, 執(zhí)行insert()
方法都會(huì)添加一條記錄, 如果values
參數(shù)為null
, 會(huì)添加一個(gè)除主鍵之外其它字段都為null
的記錄;
nullColumnHack參數(shù)作用分析SQL
語句 : 在SQL
語句中在表名后面必須跟著一個(gè)列名, 例如 " insert into appale_info(name) values("喬幫主")
", 這是values參數(shù)不為null的情況下,如果values參數(shù)為null, 那么導(dǎo)致表名 "apple_info" 后面的列名也為null, 這樣SQL語句就不合法了, 因此這里必須加上一個(gè)默認(rèn)的列名, 以防values參數(shù)為null;
HttpURLConnection
設(shè)置請求頭或響應(yīng)頭
HTTP
請求允許一個(gè)key
帶多個(gè)用逗號(hào)分開的values
,但是HttpURLConnection
只提供了單個(gè)操作的方法:
setRequestProperty(key,value)
addRequestProperty(key,value)
setRequestProperty
和addRequestProperty
的區(qū)別就是谬俄,setRequestProperty
會(huì)覆蓋已經(jīng)存在的key
的所有values
柏靶,有清零重新賦值的作用。而addRequestProperty
則是在原來key的基礎(chǔ)上繼續(xù)添加其他value
溃论。
發(fā)送URL請求
建立實(shí)際連接之后屎蜓,就是發(fā)送請求,把請求參數(shù)傳到服務(wù)器钥勋,這就需要使用outputStream
把請求參數(shù)傳給服務(wù)器:
getOutputStream
獲取響應(yīng)
請求發(fā)送成功之后炬转,即可獲取響應(yīng)的狀態(tài)碼,如果成功既可以讀取響應(yīng)中的數(shù)據(jù)算灸,獲取這些數(shù)據(jù)的方法包括:
getContent
getHeaderField
getInputStream
對(duì)于大部分請求來說扼劈,getInputStream
和getContent
是用的最多的。
相應(yīng)的信息頭用以下方法獲确坡俊:
getContentEncoding
getContentLength
getContentType
getDate
getExpiration
getLastModifed
任何網(wǎng)絡(luò)連接都需要經(jīng)過socket
才能連接荐吵,HttpURLConnection
不需要設(shè)置socket
,所以赊瞬,HttpURLConnection
并不是底層的連接先煎,而是在底層連接上的一個(gè)請求。這就是為什么HttpURLConneciton
只是一個(gè)抽象類巧涧,自身不能被實(shí)例化的原因薯蝎。HttpURLConnection
只能通過URL.openConnection()
方法創(chuàng)建具體的實(shí)例。雖然底層的網(wǎng)絡(luò)連接可以被多個(gè)HttpURLConnection
實(shí)例共享谤绳,但每一個(gè)HttpURLConnection實(shí)例只能發(fā)送一個(gè)請求
占锯。請求結(jié)束之后袒哥,應(yīng)該調(diào)用HttpURLConnection
實(shí)例的InputStream
或OutputStream
的close()
方法以釋放請求的網(wǎng)絡(luò)資源,不過這種方式對(duì)于持久化連接沒用烟央。對(duì)于持久化連接
统诺,得用disconnect()
方法關(guān)閉底層連接的socket
。
ViewStub疑俭、include粮呢、merge
Json
一種輕量級(jí)的數(shù)據(jù)交換格式,具有良好的可讀和便于快速編寫的特性钞艇∽墓眩可在不同平臺(tái)之間進(jìn)行數(shù)據(jù)交換。
JSON
采用兼容性很高的文本格式哩照,同時(shí)也具備類似于C語言體系的行為挺物。
優(yōu)點(diǎn):
-
數(shù)據(jù)格式比較簡單,易于讀寫飘弧,格式都是壓縮的识藤,占用帶寬小
; 易于解析
- 支持多種語言次伶,包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等服務(wù)器端語言痴昧,便于服務(wù)器端的解析;
- 因?yàn)镴SON格式能直接為服務(wù)器端代碼使用冠王,大大簡化了服務(wù)器端和客戶端的代碼開發(fā)量赶撰,且完成任務(wù)不變,并且易于維護(hù)柱彻。
缺點(diǎn):
- 沒有XML格式這么推廣的深入人心和喜用廣泛豪娜,沒有XML那么通用性;
- JSON格式目前在Web Service中推廣還屬于初級(jí)階段
Android中Parcelable和Serializable
作用:
Serializable的作用是為了保存對(duì)象的屬性到本地文件哟楷、數(shù)據(jù)庫瘤载、網(wǎng)絡(luò)流、rmi以方便數(shù)據(jù)傳輸卖擅,當(dāng)然這種傳輸可以是程序內(nèi)的也可以是兩個(gè)程序間的惕虑。簡單易用,
這種方法的缺點(diǎn)是使用了反射
磨镶,序列化的過程較慢
。這種機(jī)制會(huì)在序列化的時(shí)候創(chuàng)建許多的臨時(shí)對(duì)象健提,容易觸發(fā)垃圾回收
琳猫。
而Android的Parcelable的設(shè)計(jì)初衷是因?yàn)?code>Serializable效率過慢,為了在程序內(nèi)不同組件間以及不同
Android
程序間(AIDL
)高效的傳輸數(shù)據(jù)而設(shè)計(jì)私痹,這些數(shù)據(jù)僅在內(nèi)存中存在
脐嫂,Parcelable
是通過IBinder
通信的消息的載體统刮。
效率
Parcelable的性能比Serializable好,在內(nèi)存開銷方面較小账千,所以在內(nèi)存間數(shù)據(jù)傳輸時(shí)推薦使用Parcelable侥蒙,如activity間傳輸數(shù)據(jù),而Serializable可將數(shù)據(jù)持久化方便保存匀奏,所以在需要保存或網(wǎng)絡(luò)傳輸數(shù)據(jù)時(shí)選擇Serializable鞭衩,因?yàn)閍ndroid不同版本Parcelable可能不同,所以不推薦使用Parcelable進(jìn)行數(shù)據(jù)持久化
從上面的設(shè)計(jì)上我們就可以看出優(yōu)劣了娃善。
- 整個(gè)讀寫全是在內(nèi)存中進(jìn)行论衍,所以效率比JAVA序列化中使用外部存儲(chǔ)器會(huì)高很多;
- 讀寫時(shí)是4字節(jié)對(duì)齊的
- 如果預(yù)分配的空間不夠時(shí)聚磺,會(huì)一次多分配50%坯台;
- 對(duì)于普通數(shù)據(jù),使用的是mData內(nèi)存地址瘫寝,對(duì)于IBinder類型的數(shù)據(jù)以及FileDescriptor使用的是mObjects內(nèi)存地址蜒蕾。后者 是通過
flatten_binder()
和unflatten_binder()
實(shí)現(xiàn)的,目的是反序列化時(shí)讀出的對(duì)象就是原對(duì)象而不用重新new一個(gè)新對(duì)象焕阿。
后期持續(xù)更新咪啡。。捣鲸。瑟匆。。栽惶。