一個前端程序猿的一個月原生 Android 開發體驗。javascript
自從我寫了 Android 應用後,上知乎的時間變得更長了。css
自從我寫了 Android 應用後。上知乎的時間變得更長了。哦。不正確。你理解錯了,個人意思是:編譯代碼、打包 APK、執行在設備上需要時間。可不像前端,一保存代碼,就本身主動刷新頁面。html
是的。從上上週一開始,因爲項目缺人的緣由,做爲一個有 Java 開發經驗的大前端。我又又雙叕進入了原生 Android 開發的世界。前端
這一個月下來,也算是有一些寫 XML 的心得吧——不正確,寫 Java 代碼,看 Kotlin 代碼的心得。java
總的來講,Android 與前端的差別並不是很是大,在某些東西上,他們仍是蠻相似的。怪不得像我這種程序猿,會將 Android 開發也歸類到大前端上去。android
假設你是一個前端程序猿。想學習移動開發。又或者是一個移動開發,想接觸前端開發。那麼。本文可能就很是適合你去了解二者間的差別。編程
本文包括了下面的內容:swift
編碼效率 vs 可維護度設計模式
MVP vs MV:後天的 MV*瀏覽器
靜態語言 vs 動態語言
View 與 DOM
代碼調試
兼容性
(PS:受限於我僅僅有短暫的經驗,因此有些用詞可能沒有那麼準確。)
注
:這裏的前端應用特指單頁面應用。
因爲從執行效率上來講,原生應用必須遠遠大於 WebView——畢竟 WebView 的背後仍是原生應用。直接等於中間多了一個層級。因此,在這裏直接討論編碼效率。
Web
從編碼效率上來講,仍是前端快。快得不止一點點。
更快的預覽速度。
成熟的生態系統。
大量可用的 UI 框架及組件。
參考別家的實現。Web 前端是開放的世界。在今天來看,要實現的效果基本上已經被實現過了。因此咱們可以直接參考
富文本支持好
而考慮到 Android 和 iOS 是各自實現的,那麼一個混合應用的開發效率多是遠遠大於 2 倍。而跨平臺應用(如 React Native、Weex、NativeScript) 的開發效率會接近他們的 2 倍(緣由是:集成某些功能時,需要原生代碼來實現,這時工做量直接翻倍等同)。
Android
從眼下的維護程度上來講。仍是 Java 的代碼相對維護。主要是前端領域的變化太快了。並且在軟件project上的實踐不像 Java 是必需要求的,所以easy出現大量的遺留代碼。僅僅是考慮到,Java 代碼的臃腫,仍是改用 Kotlin 吧。
僅僅需要按下: Command + Alt + Shift + K。輕鬆當爸爸。
MVP,即 Model-View-Presenter,相應於視圖層-數據層-展現層。
在 MVP 上來看,前端應用與 Android 都並不是天生的 MVP 架構的。只是。二者在對業務邏輯上的處理,但是沒有多少差別。惟一能體驗差別的,可能就是 JavaScript 的異步。以及 Java 的同步帶來的一些差異。
採用了框架的前端應用,則會所以而帶上 MV* 的加成。
一旦選用上了某個框架,那麼你僅僅能依照其特有的模式,如 Vue 提供的核心是 MVVM 中的 VM,React 則僅僅是 MVC 中的 View 層。則 Angular 則多是 MVW(Model-View-Whatever)。
在這種狀況下,要在框架的基本之上變動。那麼靈活性上可能沒有那麼大。
而 Android 方面則是 MVP 架構。其主要依賴於約定俗成。當中一個參考的規範就是 Google 官方的 android-architecture,又或者是社區上推薦的 Clean Architecture。
而不論是 Clean Architecture。仍是 MVP。其都依賴於約定。
一旦咱們談及參考的時候,便意味着靈活性——可遵循。可不遵循。
在這種時候。Android 的 MVP 需要咱們本身去建立 MVPView。建立 Presenter。
public class MainActivity extends AppCompatActivity implements MainView {
...
}
而整個 MainActivity
僅僅是一個 View 層,真正的業務邏輯要交給 Presenter 來處理。簡單來講,就是你需要手動地建立四五個類,才幹完畢一個 Activity 的 Hello, world。
與此同一時候。Android 默認是要對 Model 進行校驗和轉換的。
因爲取出 JSON 中的某個值,需要將 JSON 轉換爲對象——可以直接使用 Retrofit 庫來轉換數據。又或者用 GJSON 轉換成某種對象。算是與前端的一個大的差異,在前端世界裏,這種事情是垂手可得的。有萬能的 JSON.parse
。
在使用 JavaScript 編寫的時候。可以不正確 Model 進行校驗。只是,在 React 裏會有proptypes
,在 Angular 裏可以用 TypeScript 來作相似的事。
與沒有對象校驗的前端相比。一旦出錯。根本不easy察覺。這一點,或者也是一個優點所在——當你上架了新版本號的 API 時,舊的應用不會 NullPointerException。與此同一時候,在開發的時候。後臺 API 發生變化的時候,也會致使興許的一系列 bug。
自從我寫了 Android 應用後,上知乎的時間變得更長了。
當咱們編寫 Web 應用的時候,僅僅要一保存代碼,網頁就可以由 LiveReload
這種工具來幫咱們本身主動刷新。因而。在諸如 React Native 這種跨平臺框架裏。也有 Live Reload 這種特性。
而當我開發 Android 應用的時候。每次我想試着在手機上查看效果的時候。得構建、編譯代碼、安裝,大概得等上個兩三鍾才幹執行在虛擬機或者真機上。
可事件每每不會這麼順利。動不動會趕上個 NullPointerException
,而後應用就 Crash 了。
這個時候,就要去修復代碼中的問題,加個 blabla!=null
,而後編譯,繼續 Crash。
怪不得 Android 的程序猿喜歡上了 Kotlin,僅僅要一個 view?
就能推斷是否是有值的事:
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater?.inflate(R.layout.fragment_home, container, false)
val button: Button = view!!.findViewById(R.id.open_rn_button)
button.setOnClickListener(this)
return view
}
可因爲沒有經驗,我經常把 val
寫成了 var
。這就和那些習慣寫 alloc init 的 iOS 程序猿,一晚上間忽然喜歡上了寫 ES6 同樣:
let className = NSStringFromClass(MyClass)
let classType = NSClassFromString(className) as? MyClass.Type
if let type = classType {
let my = type.init()
}
哦,不正確他們寫的是 Swift。
並且做爲一個面向對象的語言,Java 天生就意味着,大量的臃腫代碼。
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
大量的代碼,就意味着大量的 bug
。必定量的反覆代碼。一會兒又回到設計模式的天下。
好在。因爲 Android Studio 有強大的、良好的 Intellij 支持。
在 IDE 上對語言的支持,要比 JavaScript 的第三方庫支持友好得多:
要知道 WebStorm 或者 Intellj IDEA 專業版,它們在 JavaScript 第三方類的支持上就是坑。
過去,前端在 DOM 操做上存在自然的問題,即在咱們使用 $("*")
的時候,全局。
固然現今的框架,在這個問題上比較少,但是考慮到仍然可能會被誤用。或者注入。而 Android 則是局部頁面的。
前端使用 HTML + CSS 來編寫樣式,而安裝則僅僅使用 XML 來切圖。這並不是一件easy的事。不像 CSS 可以經過 「繼承」 和 「覆寫」 的形式來實現樣式複用。Android 中也有相似於 JavaScript 生成 HTML 的方式。本身定義模板。
當咱們使用 React 編寫組件的時候,可以傳遞相應的屬性到組件中,這個屬性可以是函數、值、組件等等。
MyComponent.propTypes = {
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalElement: PropTypes.element
}
而在 Android 的佈局上,這就不是同樣easy的事。爲了複用樣式,需要抽取成 UI 組件。還僅僅能是 UI 上的組件。僅僅能實現 HTML + CSS 上的複用。
HTML + CSS 在編寫 UI 的時候,有各類奇技淫巧,比方說樣式的優先級,或者 important
。
從原生的角度來看,前端的 document.getElementById()
與 Android 的 findViewById
並無多大的差異。
而當前端有了前端框架以後,就不同了。
好在 Android 有 ButterKnife 這種 View 注入框架。
與此同一時候,Android 還自帶了雙向的 DataBinding,而原生的前端是沒有的。
僅僅是前端有前端框架。在這一點也全然問題也很少。
還好,已經有寫 React Native 佈局的一些經驗。在寫起 Android 的佈局,倒也還好——沒有那麼坑。
在佈局調試上。仍是前端用瀏覽器調式方便——還可以在瀏覽器實時改動 DOM 結構。Android 也有這種工具,叫Layout Inspector:
除此,還可以經過 Facebook 家的 stetho 作與 Web 相關的調試工做:
總的來講。還算是不錯的。就是這個結構,看上去和 React Native 怎麼那麼樣呢?
在代碼調試上來講。Java 底子厚,總的來講會比 JavaScript 好一些。
除此。記得咱們在 Chrome 瀏覽器裏可以打斷點,隨後在 Console 中作出一些計算。
而得益於 Android Studio 背後的 JetBrain 的 Evaluating Expressions。可以實時計算表達式的值。Android 上的代碼調試也是很是easy的。
而以我有限的 Objective-C 編程經驗來講,XCode 也是可以作到的。
在 Chrome 瀏覽器裏,自帶的 NetWorks 差點兒是萬能的。
Android 方面也可以藉助於 Stetho
來使用:
但是依賴上比較大,需要在頁面上注入,並且調試不了插件化的應用。要調試網絡吧。仍是 Charles 好用一些。
但是,萬一開發環境 HTTPS 了呢,不就更麻煩了。
前端面臨的是調試不一樣的瀏覽器,又或者是兼容 IE。總的來講,問題都不大——不會面臨閃退的問題。即便出了點小問題。用戶可以先換個瀏覽器試試。
而當你的 Android 應用在用戶的手機上閃退了。那麼用戶僅僅能換個 APP 了。
除此,Android 則是面臨碎片化的系統。不一樣的版本號,及不一樣的屏幕大小,總的來講。要對前端複雜得多。
Android 在軟件project上作得至關優秀,而前端則是在開發效率上佔優點。
Web 開發大法好。