//Activity間使用Intent傳遞數(shù)據(jù)的兩種寫法下面均是偽代碼形式,請忽略一些細(xì)節(jié)//寫法一//SrcActivity傳遞數(shù)據(jù)給DestActivityIntent intent=new Intent(this,DestActivity.class);
intent.putExtra("param","clock");
SrcActivity.startActivity(intent);//DestActivity獲取SrcActivity傳遞過來的數(shù)據(jù)String param=getIntent.getStringExtra("param");//寫法二//SrcActivity傳遞數(shù)據(jù)給DestActivityIntent intent=new Intent(this,DestActivity.class);
intent.putExtra(DestActivity.EXTRA_PARAM,"clock");
SrcActivity.startActivity(intent);//DestActivity獲取SrcActivity傳遞過來的數(shù)據(jù)public final static String EXTRA_PARAM="param";String param=getIntent.getStringExtra(EXTRA_PARAM);
寫法一,存在的問題是,如果SrcActivity和DestActivity哪個(gè)把“param”打錯(cuò)成“para”或者“paran”,傳遞的數(shù)據(jù)都無法成功接收到。而寫法二則不會(huì)出現(xiàn)此類問題,因?yàn)閮蓚€(gè)Activity之間傳遞數(shù)據(jù)只需要知道EXTRA_PARAM變量即可,至于EXTRA_PARAM變量到底是“param”、“para”、”paran”這一點(diǎn)并不需要關(guān)心,這就是一種對可能發(fā)生變化的地方進(jìn)行抽象封裝的體現(xiàn),它所帶來的好處就是降低手抖出錯(cuò)的概率,同時(shí)方便我們進(jìn)行修改。
基于抽象和封裝,Java本身很多API在設(shè)計(jì)上就有這樣的體現(xiàn),如Collections中的很多排序方法:
這些方法都是基于List這個(gè)抽象的列表接口進(jìn)行排序,至于這是一個(gè)用什么樣的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)List(ArrayList還是LinkedList),排序方法本身并不關(guān)心。看,是不是體現(xiàn)了JDK的設(shè)計(jì)人員的一種抽象編程的思維,因?yàn)長ist的具體實(shí)現(xiàn)可能有千萬種,如果每一類List都要寫一套排序方法,估計(jì)要哭瞎了。
小結(jié):把容易出現(xiàn)變化的部分進(jìn)行抽象,就是對變化的一種封裝。
網(wǎng)絡(luò)訪問框架:OKHttp、retrofit、android-async-http、volley
圖片加載框架:Android-Universal-Image-Loader、Glide、Fresco、Picasso
緩存框架:DiskLruCache、Robospice
Json解析框架:Gson、Fastjson、Jackson
事件總線:EventBus、Otto
ORM框架:GreenDAO、Litepal
還有其他各種各樣開源的自定義控件、動(dòng)畫等。除了以上提到的開源框架,也包括一些不開源的SDK
數(shù)據(jù)統(tǒng)計(jì):友盟統(tǒng)計(jì),百度統(tǒng)計(jì)…
奔潰搜集:騰訊bugly、bugtags…
云存儲(chǔ):七?!?br /> 即使通訊:環(huán)信、融云、阿里百川…
推送:小米推送、騰訊推送、百度推送…
安全加固:360加固寶、愛加密…
一般情況下,我在選擇是否引入一些開源框架主要基于以下幾個(gè)因素:
借助搜索引擎,如果網(wǎng)上有一大波資料,說明使用的人多,出了問題好找解決方案;當(dāng)然,如果普遍出現(xiàn)差評,就可以直接Pass掉了
看框架的作者或團(tuán)隊(duì),如JakeWharton大神、Facebook團(tuán)隊(duì)等。大神和大公司出品的框架質(zhì)量相對較高,可后續(xù)的維護(hù)和bug修復(fù),不容易爛尾;
關(guān)注開源項(xiàng)目的commit密度,issue的提交、回復(fù)、關(guān)閉數(shù)量,watch數(shù),start數(shù),fork數(shù)等。像那種個(gè)基本不怎么提交代碼、提issue又不怎么回復(fù)和修復(fù)的項(xiàng)目,就pass掉;
針對不開源SDK的選擇,也主要基于以下幾點(diǎn)去考慮:
借助搜索引擎,查明口碑;
很多第三方SDK的官網(wǎng)首頁都會(huì)告訴你,多少應(yīng)用已經(jīng)接入了此SDK,如果你看到有不少知名應(yīng)用在上面,那這個(gè)SDK可以考慮嘗試一下了。
查看SDK使用文檔、它們的開發(fā)者社區(qū)、聯(lián)系客服。好的SDK,使用文檔肯定會(huì)詳細(xì)指引你。出了問題,上開發(fā)者社區(qū)提問,他們的開發(fā)工程師也會(huì)社區(qū)上回答。實(shí)在不行只能聯(lián)系客服,如果客服的態(tài)度都讓你不爽,那就可以考慮換別家的SDK了。
小結(jié):選好“車輪”,事半功倍
假設(shè)你當(dāng)前為項(xiàng)目引入一個(gè)加載圖片的框架——Android-Universal-Image-Loader,最簡單的做法就是加入相應(yīng)的依賴包后,在任何需要加載圖片的地方寫上下面這樣的代碼段。
ImageLoader imageLoader=ImageLoader.getInstance();//Get singleton instance
//Load image,decode it to Bitmap and display Bitmap in ImageView(or any other view//which implements ImageAware interface)
imageLoader.displayImage(imageUri,imageView);
//Load image,decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri,new SimpleImageLoadingListener(){
Override public void onLoadingComplete(String imageUri,View view,Bitmap loadedImage){
//Do whatever you want with Bitmap
}
});
這種做法最簡單粗暴,但是帶來的問題也最嚴(yán)重的。如果我有幾十上百個(gè)地方都這么寫,而在某一天,我聽說Facebook出了個(gè)神器Fresco,想要換掉Android-Universal-Image-Loader,你就會(huì)發(fā)現(xiàn)你需要喪心病狂的去改動(dòng)幾十上百個(gè)地方的代碼,不僅量大,而且還容易出錯(cuò)。造成這樣的原因,就在于項(xiàng)目和加載圖片的框架之間形成了強(qiáng)耦合,而實(shí)際上,項(xiàng)目本身不應(yīng)該知道我具體用了哪個(gè)加載圖片的框架。
正確的方式,應(yīng)該是對框架做一個(gè)抽象的封裝,以應(yīng)對未來發(fā)生的變化,我直接舉自己的開源項(xiàng)目AndroidAlbum中的一種封裝做法好了。
這樣一來,切換框架所帶來的代價(jià)就會(huì)變得很小,這就是不直接依賴于框架所帶來的好處。當(dāng)然,以上只是我比較簡單的封裝,你也可以進(jìn)行更加細(xì)致的處理。
小結(jié):預(yù)留變更,不強(qiáng)耦合于第三方框架
View:布局的xml文件
Controller:Activity、Fragment、Dialog等
Model:相關(guān)的業(yè)務(wù)操作處理數(shù)據(jù)(如對數(shù)據(jù)庫的操作、對網(wǎng)絡(luò)等的操作都應(yīng)該在Model層里)
你會(huì)發(fā)現(xiàn),如果View層只包含了xml文件,那我們Android項(xiàng)目中對View層可做操作的程度并不大,頂多就是用include復(fù)用一下布局。而Activity等簡直就是一個(gè)奇葩,它雖然歸屬于Controller層,但實(shí)際上也干著View層的活(View的初始化和相關(guān)操作都是在Activity中)。就是這種既是View又是Controller的結(jié)構(gòu),違背了單一責(zé)任原則,也使得Activity等出現(xiàn)了上述的臃腫問題。
View:Activity、Fragment、Dialog、Adapter等,該層不包含任何業(yè)務(wù)邏輯
Presenter:中介,View與Model不發(fā)生聯(lián)系,都通過Presenter傳遞
Model:相關(guān)的業(yè)務(wù)操作處理數(shù)據(jù)(如對數(shù)據(jù)庫的操作、對網(wǎng)絡(luò)等的操作都應(yīng)該在Model層里)
相比MVC,MVP在層次劃分上更加清晰了,不會(huì)出現(xiàn)一人身兼二職的情況(有些單元測試的童鞋,會(huì)發(fā)現(xiàn)單元測試用例更好寫了)。在此處你可以看到View和Model之間是互不知道對方存在的,這樣應(yīng)對變更的好處更大,很多時(shí)候都是View層的變化,而Model層發(fā)生的變化會(huì)相對較少,遵循MVP的結(jié)構(gòu)開發(fā)后,改起來代碼來也沒那么蛋疼。
這里也有地方需要注意,因?yàn)榇罅康慕换ゲ僮骷性赑resenter層中,所以需要把握好Presenter的粒度,一個(gè)Activity可以持有多個(gè)View和Presenter,這樣也就可以避開一個(gè)碩大的View和Presenter的問題了。
小結(jié):去加以實(shí)踐的理解MVP吧
小結(jié):合理歸檔代碼,可以的話,加以開源維護(hù)
不要過早的做性能優(yōu)化,app先求能用再求好用。在需求都還沒完成的時(shí)候把大量時(shí)間花在優(yōu)化上是本末倒置的;
優(yōu)化要用實(shí)際數(shù)據(jù)說話,借助測試工具進(jìn)行檢測(如:網(wǎng)易的Emmagee、騰訊的GT和APT,科大訊飛的iTest,Google的Battery Historian)。畢竟老板問你比以前耗電降低多少,總不能回答降低了一些吧???
任何不以減低性能損耗來做?;畹氖侄危际撬A髅?。
小結(jié):合理優(yōu)化,數(shù)據(jù)量化
借助搜索引擎??创隧?xiàng)技術(shù)坑多不多,口碑不錯(cuò)但是坑多的話,則說明當(dāng)前技術(shù)不成熟,可以耐心等待更新;
考慮學(xué)習(xí)成本。學(xué)習(xí)成本太大且不容易招到懂這方面的開發(fā)者的情況下,建議不要引入該技術(shù);
高仿一個(gè)項(xiàng)目并開源。如果你想引入React Native做商業(yè)開發(fā),先高仿實(shí)現(xiàn)一個(gè)應(yīng)用然后將其開源。這樣一些對RN感興趣的開發(fā)者會(huì)運(yùn)行你的代碼并反饋bug給你,有助于你知道一些新技術(shù)的坑,并尋找相應(yīng)的解決方案,最終確定是否引入該技術(shù);
降低入門門檻。實(shí)踐新技術(shù)的過程盡量加以詳細(xì)的文檔記錄,這會(huì)有助于降低項(xiàng)目組其他同事對新技術(shù)的入門門檻,可以的話,也將學(xué)習(xí)文檔開源,獲得更多開發(fā)者對此份文檔的反饋,也可糾正一些文檔中的錯(cuò)誤;
結(jié)合實(shí)際業(yè)務(wù)。所有新技術(shù)的引入都要考慮是否符合當(dāng)下的業(yè)務(wù)需求,我聽過有些程序猿想引入新技術(shù)的原因是因?yàn)橛X得這種技術(shù)很酷,網(wǎng)上說很好用,很啥啥啥…自己完全沒弄過就人云亦云。有時(shí)候好無語,感覺在會(huì)用一些技術(shù)就像在炫技一樣。
以上就是關(guān)于“Android開發(fā)培訓(xùn)實(shí)戰(zhàn)經(jīng)驗(yàn)分享”的內(nèi)容介紹,希望對大家學(xué)習(xí)有所幫助。想要了解更多關(guān)于Android開發(fā)培訓(xùn)的相關(guān)資訊歡迎來咨詢。