重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
Flutter是谷歌公司推出的跨終端的開發框架,支持Android、iOS和WEB終端。1.0版在2018年12月5日發布,目前的最新版本是1.5,它采用的開發語言是Dart,Dart也是谷歌開發的計算機編程語言,語法類似C,是編譯型語言:
創新互聯建站主要為客戶提供服務項目涵蓋了網頁視覺設計、VI標志設計、全網營銷推廣、網站程序開發、HTML5響應式網站建設公司、成都做手機網站、微商城、網站托管及成都企業網站維護、WEB系統開發、域名注冊、國內外服務器租用、視頻、平面設計、SEO優化排名。設計、前端、后端三個建站步驟的完善服務體系。一人跟蹤測試的建站服務標準。已經為崗亭行業客戶提供了網站建設服務。
hello world例子,打印字符串“Hello World!”:
1、沒有橋接層
React Native、Weex等技術都是跨終端的框架,然而性能跟原生App存在很大差距。這是由于它們的工作原理決定的:
React Native、Weex等技術多了一個橋接層,所以界面渲染會慢一些,由于UI渲染非常頻繁,想要不卡頓,基本上比較難,性能和用戶體驗跟原生代碼有差距。而這恰恰是Flutter的優勢所在:
Dart可以被編譯成不同平臺的本地代碼,讓Flutter不通過橋接層直接跟平臺通信,自然性能會快一些。
2、編譯執行
JavaScript是解釋執行的,Dart是編譯執行的,性能誰好一目了然。
3、Flutter Engine虛擬機
Flutter是依靠Flutter Engine虛擬機在iOS和Android上運行的,Flutter Engine使用C/C++編寫,開發人員通過Flutter框架直接和API在內部進行交互,所以具有輸入低延遲和UI渲染高幀速率的特點。除了這特點之外,Flutter還提供了自己的小部件,Flutter小部件是使用從React獲取靈感的現代框架構建的。 中心思想是您使用小部件構建UI。
窗口小部件根據其當前配置和狀態描述了它們的視圖。 當窗口小部件的狀態發生更改時,窗口小部件會重建其描述,框架將根據前面的描述進行區分,以確定底層呈現樹從一個狀態轉換到下一個狀態所需的最小更改。可以直接在OS平臺提供的畫布上進行描繪,也就是一些核心類庫直接放到虛擬機里面,調用起來更快。
從它的系統結構可以看出,類似安卓的ART(Android Run Time)虛擬機,同樣采用AOT(Ahead of TIme)技術,會在APP安裝時就編譯成機器語言,不再解釋執行,從而優化了APP運行的性能。
4、自帶渲染引擎
Flutter使用谷歌自己的Skia渲染引擎,而Android系統自帶Skia引擎,iOS平臺上Flutter也會把Skia引擎打包到APP中,從而實現了高效渲染。而React Native通過橋接層訪問原生UI,操作頻繁就容易出性能問題。
綜合所述,Flutter 是性能最接近原生代碼 的一種開發框架,未來也會是構建谷歌Fuchsia應用的主要方式,前途不可限量,唯一的問題就是需要學習一門新的語言:Dart,而有Java或者C#語言基礎的程序員會比較容易學習。
文/陳爐軍
整理/LiveVideoStack
大家好,我是阿里巴巴閑魚事業部的陳爐軍,本次分享的主題是Flutter浪潮下的音視頻研發探索,主要內容是針對閑魚APP在當下流行的跨平臺框架Flutter的大規模實踐,介紹其在音視頻領域碰到的一些困難以及解決方案。
分享內容主要分為四個方面,首先會對Flutter有一個簡單介紹以及選擇Flutter作為跨平臺框架的原因,其次會介紹Flutter中與音視頻關系非常大的外接紋理概念,以及對它做出的一些優化。之后會對閑魚在音視頻實踐過程中碰到的一些Flutter問題提出了一些解決方案——TPM音視頻框架。最后是閑魚Flutter多媒體開源組件的介紹。
Flutter
Flutter是一個跨平臺框架,以往的做法是將音頻、視頻和網絡這些模塊都下沉到C++層或者ARM層,在其上封裝成一個音視頻的SDK,供UI層的PC、iOS和Android調用。
而Flutter做為一個UI層的跨平臺框架,顧名思義就是在UI層也實現了一個跨平臺開發。可以預想的是未Flutter發展的好的話,會逐漸變為一個從底層到UI層的一個全鏈路的跨平臺開發,技術人員分別負責SDK和UI層的開發。
在Flutter之前已經有很多跨平臺UI解決方案,那為什么選擇Flutter呢?
我們主要考慮性能和跨平臺的能力。
以往的跨平臺方案比如Weex,ReactNative,Cordova等等因為架構的原因無法滿足性能要求,尤其是在音視頻這種性能要求幾乎苛刻的場景。
而諸如Xamarin等,雖然性能可以和原生App一致,但是大部分邏輯還是需要分平臺實現。
我們可以看一下,為什么Flutter可以實現高性能:
原生的native組件渲染以IOS為例,蘋果的UIKit通過調用平臺自己的繪制框架QuaztCore來實現UI的繪制,圖形繪制也是調用底層的API,比如OpenGL、Metal等。
而Flutter也是和原生API邏輯一致,也是通過調用底層的繪制框架層SKIA實現UI層。這樣相當于Flutter他自己實現了一套UI框架,提供了一種性能超越原生API的跨平臺可能性。
但是我們說一個框架最終性能怎樣,其實取決于設計者和開發者。至于現在到底是一個什么狀況:
在閑魚的實踐中,我們發現在正常的開發沒有特意的去優化UI代碼的情況下,在一些低端機上,Flutter界面的流暢性是比Native界面要好的。
雖然現在閑魚某些場景下會有卡頓閃退等情況,但是這是一個新事物發展過程中的必然問題,我們相信未來性能肯定不會成為限制Flutter發展的瓶頸的。
在閑魚實踐Flutter的過程中,混合棧和音視頻是其中比較難解決的兩個問題,混合棧是指一個APP在Flutter過程中不可能一口氣將所有業務全部重寫為Flutter,所以這是一個逐步迭代的過程,這期間原生native界面與Flutter界面共存的狀態就稱之為混合棧。閑魚在混合棧上也有一些比較好的輸出,例如FlutterBoost。
外接紋理
在講音視頻之前需要簡要介紹一下外接紋理的概念,我們將它稱之為是Flutter和Frame之間的橋梁。
Flutter渲染一幀屏幕數據首先要做的是,GPU發出的VC信號在Flutter的UI線程,通過AOT編譯的機器碼結合當前Dart Runtime,生成Layer Tree UI樹,Layer Tree上每一個葉子節點都代表了當前屏幕上所需要渲染的每一個元素,包含了這些元素渲染所需要的內容。將Layer Tree拋給GPU線程,在GPU線程內調用Skia去完成整個UI的渲染過程。Layer Tree中有PictureLayer和TextureLayer兩個比較重要的節點。PictureLayer主要負責屏幕圖片的渲染,Flutter內部實現了一套圖片解碼邏輯,在IO線程將圖片讀取或者從網絡上拉取之后,通過解碼能夠在IO線程上加載出紋理,交給GPU線程將圖片渲染到屏幕上。但是由于音視頻場景下系統API太過繁多,業務場景過于復雜。Flutter沒有一套邏輯去實現跨平臺的音視頻組件,所以說Flutter提出了一種讓第三方開發者來實現音視頻組件的方式,而這些音視頻組件的視頻渲染出口,就是TextureLayer。
在整個Layer Tree渲染的過程中,TextureLayer的數據紋理需要由外部第三方開發者來指定,可以把視頻數據和播放器數據送到TextureLayer里,由Flutter將這些數據渲染出來。
TextureLayer渲染過程:首先判斷Layer是否已經初始化,如果沒有就創建一個Texture,然后將Texture Attach到一個SufaceTexture上。
這個SufaceTexture是音視頻的native代碼可以獲取到的對象,通過這個對象創建的Suface,我們可以將視頻數據、攝像頭數據解碼放到Suface中,然后Flutter端通過監聽SufaceTexture的數據更新就可以順利把剛才創建的數據更新到它的紋理中,然后再將紋理交給SKIA渲染到屏幕上。
然而我們如果需要用Flutter實現美顏,濾鏡,人臉貼圖等等功能,就需要將視頻數據讀取出來,更新到紋理中,再將GPU紋理經過美顏濾鏡處理后生成一個處理后的紋理。按Flutter提供的現有能力,必須先將紋理中的數據從GPU讀出到CPU中,生成Bitmap后再寫入Surface中,這樣在Flutter中才能順利的更新到視頻數據,這樣做對系統性能的消耗很大。
通過對Flutter渲染過程分析,我們知道Flutter底層需要渲染的數據就是GPU紋理,而我們經過美顏濾鏡處理完成以后的結果也是GPU紋理,如果可以將它直接交給Flutter渲染,那就可以避免GPU-CPU-GPU這樣的無用循環。這樣的方法是可行的,但是需要一個條件,就是OpenGL上下文共享。
OpenGL
在說上下文之前,得提到一個和上線文息息相關的概念:線程。
Flutter引擎啟動后會啟動四個線程:
第一個線程是UI線程,這是Flutter自己定義的UI線程,主要負責GPU發出的VSync信號時候用當前Dart編譯的機器碼和當前運行環境創建出Layer Tree。
還有就是IO線程和GPU線程。和大部分OpenGL處理解決方案中一樣,Flutter也采取一個線程責資源加載,一部分負責資源渲染這種思路。
兩個線程之間紋理共享有兩種方式。一種是EGLImage(IOS是 CVOpenGLESTextureCache)。一種是OpenGL Share Context。Flutter通過Share Context來實現紋理共享,將IO線程的Context和GPU線程的Context進行Share,放到同一個Share Group下面,這樣兩個線程下資源是互相可見可以共享的。
Platform線程是主線程,Flutter中有一個很奇怪的設定,GPU線程和主線程共用一個Context。并且在主線程也有很多OpenGL 操作。
這樣的設計會給音視頻開發帶來很多問題,后面會詳細說。
音視頻端美顏處理完成的OpenGL紋理能夠讓Flutter直接使用的條件就是Flutter的上下文需要和平臺音視頻相關的OpenGL上下文處在一個Share Group下面。
由于Flutter主線程的Context就是GPU的Context,所以在音視頻端主線程中有一些OpenGL操作的話,很有可能使Flutter整個OpenGL被破壞掉。所以需要將所有的OpenGL操作都限制在子線程中。
通過上述這兩個條件的處理,我們就可以在沒有增加GPU消耗的前提下實現美顏和濾鏡等等功能。
TPM
在經過demo驗證之后,我們將這個方案應用到閑魚音視頻組件中,但改造過程中發現了一些問題。
上圖是攝像頭采集數據轉換為紋理的一段代碼,其中有兩個操作:首先是切進程,將后面的OpenGL操作都切到cameraQueue中。然后是設置一次上下文。然后這種限制條件或者說是潛規則往往在開發過程中容易被忽略的。而這個條件一旦忽略后果就是出現一些莫名其妙的詭異問題極難排查。因此我們就希望能抽象出一套框架,由框架本身實現線程的切換、上下文和模塊生命周期等的管理,開發者接入框架以后只需要安心實現自己的算法,而不需要關心這些潛規則還有其他一些重復的邏輯操作。
在引入Flutter之前閑魚的音視頻架構與大部分音視頻邏輯一樣采用分層架構:
1:底層是一些獨立模塊
2:SDK層是對底層模塊的封裝
3:最上層是UI層。
引入Flutter之后,通過分析各個模塊的使用場景,我們可以得出一個假設或者說是抽象:音視頻應用在終端上可以歸納為視頻幀解碼之后視頻數據幀在各個模塊之間流動的過程,基于這種假設去做Flutter音視頻框架的抽象。
咸魚Flutter多媒體開源組件
整個Flutter音視頻框架抽象分為管線和數據的抽象、模塊的抽象、線程統一管理和上下文同一管理四部分。
管線,其實就是視頻幀流動的管道。數據,音視頻中涉及到的數據包括紋理、Bit Map以及時間戳等。結合現有的應用場景我們定義了管線流通數據以Texture為主數據,同時可以選擇性的添加Bit Map等作為輔助數據。這樣的數據定義方式,避免重復的創建和銷毀紋理帶來的性能開銷以及多線程訪問紋理帶來的一些問題。也滿足一些特殊模塊對特殊數據的需求。同時也設計了紋理池來管理管線中的紋理數據。
模塊:如果把管線和數據比喻成血管和血液,那框架音視頻的場景就可以比喻成器官,我們根據模塊所在管線的位置抽象出采集、處理和輸出三個基類。這三個基類里實現了剛才說的線程切換,上下文切換,格式轉換等等共同邏輯,各個功能模塊通過集成自這些基類,可以避免很多重復勞動。
線程:每一個模塊初始化的時候,初始化函數就會去線程管理的模塊去獲取自己的線程,線程管理模塊可以決定給初始化函數分配新的線程或者已經分配過其他模塊的線程。
這樣有三個好處:
一是可以根據需要去決定一個線程可以掛載多少模塊,做到線程間的負載均衡。第二,多線程并發式能夠保證模塊內的OpenGL操作是在當前線程內而不會跑到主線程去,徹底避免Flutter的OpenGL 環境被破壞。第三,多線程并行可以充分利用CPU多核架構,提升處理速度。
從Flutter端修改Flutter引擎將Context取出后,根據Context創建上下文的統一管理模塊,每一個模塊在初始化的時候會獲取它的線程,獲取之后會調用上下文管理模塊獲取自己的上下文。這樣可以保證每一個模塊的上下文都是與Flutter的上下文進行Share的,每個模塊之間資源都是共享可見的,Flutter和音視頻native之間也是互相共享可見的。
基于上述框架如果要實現一個簡單的場景,比如畫面實時預覽和濾鏡處理功能,
1:需要選擇功能模塊,功能模塊包括攝像頭模塊、濾鏡處理模塊和Flutter畫面渲染模塊,
2:需要配置模塊參數,比如采集分辨率、濾鏡參數和前后攝像頭設置等,
3:在創建視頻管線后使用已配置的參數創建模塊
4:最后管線搭載模塊,開啟管線就可以實現這樣簡單的功能。
上圖為整個功能實現的代碼和結構圖。
結合上述音視頻框架,閑魚實現了Flutter多媒體開源組件。
組要包含四個基本組件分別是:
1:視頻圖像拍攝組件
2:播放器組件
3:視頻圖像編輯組件
4:相冊選擇組件
現在這些組件正在走內部開源流程。預計9月份,相冊和播放器會實現開源。
后續展望和規劃
1:實現開頭所說的從底層SDK到UI的全鏈路的跨端開發。目前底層框架層和模塊層都是各個平臺各自實現,反而是Flutter的UI端進行了跨平臺的統一,所以后續會將底層也按照音視頻常用做法把邏輯下沉到C++層,盡可能的實現全鏈路跨平臺。
2:第二部分內容為開源共建,閑魚開源的內容不僅包括拍攝、編輯組件,還包括了很多底層模塊,希望有開發者在基于Flutter開發音視頻應用時可以充分利用閑魚開源出的音視頻模塊能力,搭建APP框架,開發者只要去負責實現特殊需求模塊就可以,盡可能的減少重復勞動。
本文面向 Flutter 初學者,旨在用易懂的方式帶大家入門。除了 Flutter 代碼,還會介紹到語法、原理、特性等基礎知識。相信本文能幫助你學習和理解 Flutter。
我們先看一下目前的一些跨平臺方案,從前端渲染的角度來分類的話,大致可以分為以下幾種方案。
WebView 渲染
這種方案就很好理解,現在很多項目都會嵌入 H5 的頁面。就是用 JavaScript 等前端技術進行開發,在客戶端上用 WebView 來進行渲染。微信小程序目前使用的就是這種方案。
它的優點很明顯,使用成熟的前端技術進行開發,學習成本低,開發效率高,并且支持動態發布代碼。
但缺點也很明顯,在性能體驗上,和原生還是存在較大差距的。
原生控件渲染
既然 WebView 的性能不夠好,于是就有了使用原生控件進行渲染的方案。這種方案,同樣也是使用 JavaScript 開發,區別是它最終是調用原生控件進行渲染的。這種方案的代表是 Facebook 的 React Native。
由于使用原生控件進行渲染,性能體驗也會更接近原生。但也只是更接近,和原生還是有差距的,因為它需要頻繁的進行 JavaScript 和原生之間的通信,這個通信效率是比較低的。
另外,由于需要適配各個平臺的控件,那就有可能出現,系統控件更新了,而框架本身還沒有更新,由此產生了一些問題。換句話說,這種方案是受到原生控件限制的。
繪圖引擎渲染
接下來就是主角了。
在前端,如果完全不使用原生控件,我們可以通過系統的繪圖 API 繪制出一個用戶界面。從這個角度出發,可以在各個平臺使用一個統一接口的繪圖引擎來進行界面繪制,這個引擎最終調用的是系統的 API 繪制的。這樣的話,它的性能可以做到接近原生,并且又不受原生控件的限制,在不同平臺上能夠做到 UI 統一。
Flutter 就是這樣的一個開發框架。
一個跨平臺 UI 解決方案
Flutter 是由 Google 開發的,一個跨平臺 UI 解決方案。換句話說,它原則上只管 UI 的問題,如果涉及到平臺本身的一些功能,比如調用藍牙、攝像頭,一般還是需要原生代碼去操作。但現在也會有一些第三方庫幫我們解決這些問題。
繪圖引擎 Skia
Flutter 使用 Skia 作為它的繪圖引擎。Skia 已經被 Google 收購,目前很多 Google 旗下的產品都是用 Skia 繪制的,包括 Android。
Android 內置了 Skia,但 iOS 沒有,所以在打 iOS 安裝包的時候,會把 Skia 一起打進去。這就導致了,用同一份 Flutter 代碼打包之后,iOS 的包要比 Android 的包大一些。
開發語言 Dart
Flutter 使用的開發語言,叫 Dart。Dart 也是 Google 自家的,它是一門面向對象的語言,從它身上會看到一些其他開發語言的影子。學習起來難度不大的。
前面講跨平臺方案的時候,可以發現別的方案基本都是用 JavaScript 作為開發語言的,但為什么 Flutter 不用?就因為 Dart 是谷歌自家的嗎?這個問題先留著,我們后面會提到。
這里部分就簡單點帶過了,具體的搭建流程可以在官網查看:
主要的搭建步驟如下:
下載 Flutter SDK
官網下載地址:
由于在國內訪問可能受限,官方為中國開發者搭建了鏡像:
更新環境變量
解壓后,將 flutter\bin 的全路徑添加到環境變量 PATH 中。
安裝開發工具
理論上,任何文本編輯器都可以用來開發 Flutter 應用,但推薦的開發工具是 Android Studio、IntelliJ 以及 VS Code。因為在這些開發工具上,可以安裝官方的 Flutter 和 Dart 插件,得到更好的開發體驗。文章里使用 Android Studio 來演示。
如果你打算開發 iOS 應用,則還需要安裝 Xcode。
安裝插件
在開發工具的插件設置中,安裝上面說到的 Flutter 和 Dart 插件。Flutter 插件用于支持 Flutter 的運行、調試、熱重載等功能,而 Dart 插件則提供了代碼的輸入校驗、代碼補全等功能。
萬物始于 Hello World,我們先來創建一個顯示 Hello World 的 Flutter 項目。
在 Android Studio 的歡迎頁面選擇 Start a new Flutter project ,或者通過菜單欄的 File New New Flutter Project ,創建一個新的 Flutter 項目。
創建好的項目里面包含了 android 和 ios 兩個文件夾,它們是標準的 Android 和 iOS 項目。我們的 Flutter 代碼,存放在 lib 文件夾里。項目創建好后,會默認帶一個計數器的示例,我們不管它,把 main.dart 的代碼改成 Hello World:
啟動一個模擬器,或者連上真機,點擊 Run 運行一下,就能看這樣一個界面了:
具體代碼先混個眼熟就好,具體的后面會再講到。
在寫 Flutter 之前,還要先跟大家簡單介紹一下 Dart 的語法。如果你有 Java 或 JavaScript 的開發經驗,以及面向對象的編程思想,學起來是很快的。
我們可以在 test 文件夾下新建一個 dart 文件,用來寫測試代碼。
指定類型
var
但和 JavaScript 不同的是,以下代碼在 JavaScript 是不會報錯的,但在 Dart 里會報錯:
Object
如果非要上面這樣寫,那也可以。把 var 換成 Object 就不報錯了:
和 Java 類似,Object 是所有對象的根基類。但是這樣的話,如果想打印一下 num 的字符串長度,是會報錯的:
因為 length 是屬于 String 的,但系統只知道 num 是一個對象,并不知道它是一個 String。
dynamic
如果還是非要這樣寫,那也可以。Dart 有一個特有的關鍵字 dynamic,把 Object 改成 dynamic 就不報錯了:
我們運行一下這個文件,可以在控制臺看到正確打印出了字符串長度。
函數
dynamic
在 Dart 里,函數也是可以不寫返回類型的,不寫的話會被當做 dynamic 來處理。這樣的話,函數的類型就是 return 的類型,如果沒有 return 則是 void 類型。比如可以這樣:
運行之后是能正確打印出字符串長度的。
用于傳參
Dart 里的函數也是一個對象,所以可以把函數作為參數來傳遞,比如:
可選參數
在 Dart 的函數傳參里,有一個叫可選參數的概念,我們以文字控件 Text 為例,在源碼里可以看到 Text 的構造函數是這樣的:
首先,在參數里有一個 data,它是要顯示的文字內容,是一個必填項。而 data 后面的一堆參數,是用一個大括號括起來的,這些參數就叫做可選參數,意思是這些參數可傳可不傳。
假如我們要顯示一個比較長的文字,又想限制它最多顯示兩行,就可以這樣來創建一個 Text:
可選參數,在 Flutter 里面用的非常多。
異步
Future
在 Dart 里使用 Future 來處理異步任務,比如我們現在延時一秒打印 666,代碼如下:
Future 的語法和 Promise 非常像。任務執行成功會調用 then,執行失敗會調用 catchError,而無論成功還是失敗,都會調用 whenComplete。
async/await
如果你不喜歡上面那種寫法,或者是想把異步轉成同步,就可以用 async 和 await 這兩個關鍵字來轉換。
我們把上面的代碼轉換一下,寫一個 getString 方法,返回的類型是 Future,它會延時返回一個字符串。在 main 函數后面加上 async 關鍵字,在 getString() 前面加上 await,代碼如下:
運行之后可以看到,能正常延時一秒后,把字符串打印出來。這里 getString() 返回的類型是 Future,而 await getString() 則是返回了延時之后返回的字符串。await 要在 async 的函數里面才能使用。
async 和 await 其實是一個語法糖,它最終也是轉換成 Future 調用鏈的形式執行的。
接下來回到 Flutter,Flutter 里最重要的一個概念是 Widget(下面翻譯作控件)。
在原生開發里面,我們可能會在界面上區分,這是一個 View,這是一個 Layout,這是一個 View Controller。但在 Flutter 里面,它們全都屬于一個統一的模型 Widget。可以說,在 Flutter 界面里,所有東西都是 Widget。
以前學面向對象的時候,我們都聽過一句話,叫萬物皆對象。我這里套用一下,在 Flutter 里, 萬物皆控件 。
具體有哪些控件,我做了一下簡單的分類。
根控件
所有的控件都屬于 StatefulWidget 或 StatelessWidget 。它們的區別是,StatefulWidget 擁有狀態 State ,而 StatelessWidget 沒有。
StatefulWidget
當一個控件是可變的時候,就要使用 StatefulWidget 來構建。StatefulWidget 本身不可變,但它持有的狀態 State 是可變的。
StatelessWidget
當一個控件狀態是固定不可變的時候,就可以使用 StatelessWidget。前面我們寫的 Hello World 就是使用 StatelessWidget。
容器控件
容器類控件一般是將某些屬性或配置,作用在它的子控件上,比如控件所在的寬高、背景、位置等。
常用的容器控件有 Container、Center、Padding 等。
布局控件
布局控件可以類比作原生開發中的 Layout,通常它會擁有一個 children 的屬性,用于接收一個控件數組,對這些控件進行特定的排版。
常用的布局控件有 Row、Column、Stack、Flex 等。
基礎控件
基礎控件就是常用的文字、按鈕、圖片等控件。
常用的基礎控件有 Text、TextField、Button、Image 等。
功能控件
在 Flutter 里還有一類控件,它們不影響 UI 布局,但帶有一些特定的功能,比如頁面跳轉、事件監聽、定義主題等。我們把這一類控件稱作功能控件。
常用的功能控件有 Navigator、NotificationListener、Theme 等。
開始寫 Flutter 代碼了。還記不記得,在 Flutter 項目創建之后,是自帶一個計數器 demo 的,現在我們用自己的代碼實現一遍。代碼修改成如下:
運行之后,就可以看到這樣的界面了:
按鈕每點擊一次,數字就會加一。下面我們來分析一下這段代碼,看下里面用到的一些 Widget。
StatefulWidget
由于頁面中的數字是跟隨狀態變化的,所以該頁面改用 StatefulWidget。StatefulWidget 并不會直接返回一個 Widget,而是返回狀態 State,在 State 里再返回 Widget。
Scaffold
Scaffold 是一個標準的 Material Design 頁面,它包含了標題欄、浮動按鈕、側滑菜單、底部導航欄等配置。我們這里用到了標題欄 appBar、頁面內容 body、浮動按鈕 floatingActionButton。
AppBar
AppBar 就是標題欄,通過查看控件的構造方法,我們可以知道它可配置的屬性。
AppBar 的可選參數除了標題 title,還可以配置標題前的內容 leading,右側的操作按鈕 anctions,控件垂直高度 elevation 等。我們只傳了 title,其他屬性都用默認值。
Center
Center 是一個容器類控件,它的作用就是讓它的子控件居中顯示。
FloatingActionButton
熟悉安卓開發的應該對這個控件比較熟悉,它就是頁面右下角一個特定樣式的 Button,參數里面的 onPressed 是一個必填項,要傳一個點擊之后的回調函數。
根據這個例子,下面給大家介紹一下 Flutter 兩個比較重要的特性。
點擊 Button 之后,我們把 num 變量加一,并使用 setState 通知狀態發生了改變,Flutter 會根據新的狀態更新 UI。如果有接觸過小程序開發,setState 就和小程序的 setData 類似。
在 Flutter 里面我們不需要用 set 方法來更新 UI,可變控件是和狀態綁定的,這就是 Flutter 的響應式 UI 編程。
在 Android Q 和 iOS 13 里都加入了暗黑模式,我們也換一個暗黑主題來玩一下。MaterialApp 里有一個 theme 的屬性,我們把它配置一下:
這次改完之后不點 Run 了,我們點一下閃電圖標 Flutter Hot Reload ,就能看到界面發生了變化:
這就是 Flutter 的 熱重載 ,在修改完代碼之后,通過熱重載就能馬上在設備上看到修改結果,可以很大程度上增加開發效率。
下面再給大家介紹幾個 Flutter 里的常見操作。
在 Flutter 里,使用 Navigator 來管理頁面跳轉,比如要跳轉到一個 NewPage 可以這樣寫:
進棧使用 push,出棧則是 pop。
使用 MaterialPageRoute 會模擬出 Android 上頁面跳轉的過場效果。
我們來看看怎么顯示一張本地圖片。
先在根目錄新建一個存放圖片的文件夾,比如叫 images,把圖片 picture.png 放進去。
找到根目錄下的 pubspec.yaml 文件,這個便是 Flutter 依賴配置文件,我們需要在這里配置一下剛才的圖片:
這樣,我們就能使用 Image 控件把這張圖片顯示出來了:
和 node 的 npm 以及 Android 的 jcenter 類似,Flutter 也擁有一個公共倉庫 pub.dev。pub.dev 是 Google 官方的 Dart 倉庫,在上面可以找到我們需要的包和插件。
Flutter 本身沒有 Toast,我們來接入一個。在 pub.dev 上搜索后,我決定使用 fluttertoast:
按照說明,在 pubspec.yaml 文件里的 dependencies 下配置:
點一下 Android Studio 右上角的 Packages get 同步之后就可以使用了:
我們上面使用的都是 Material Design 的控件,它們都是在 flutter/material.dart 包里面的。如果要使用 iOS 風格的控件,則要用到 flutter/cupertino.dart 包:
iOS 風格的控件,基本都以 Cupertino 開頭。我們把計時器頁面里的控件替換一下:
效果如下:
代碼的部分就到這里了,接下來跟大家聊一下編譯方式,編程語言的編譯方式有兩種。
關于它們孰優孰劣,就要看從哪個角度去對比了。JIT 的話,它的一大特點就是支持動態發布代碼,也就是支持熱更新。但要是從性能的角度考慮,AOT 會更好,因為在運行的時候不用再進行編譯的操作的,運行的效率會更高一些。
回到我們一開始的時候留下的問題,為什么別的跨平臺方案都是用 JavaScript,而 Flutter 要用 Dart 來開發。JavaScript 的編譯方式是 JIT 的,它不支持 AOT。而 Dart 同時支持 JIT 和 AOT。
Flutter 在開發階段使用 JIT,讓我們用上了熱重載,增加了開發效率。在打包時改用 AOT,保證了正式版應用的性能。
最后講一下大家比較關心的一個東西,Flutter 是否支持熱更新?前面說到 Dart 支持 JIT,所以從技術層面它是支持的。但是目前是不支持的,在官方的計劃文檔中,可以看到:
至于原因,官方在這里進行了說明。總的來說,是由于政策的限制,以及出于對性能和安全性的考慮,暫時不支持了。
到這就結束啦。由于想把 Flutter 基礎在一篇內講完,沒有涉及太多細節,如果要寫 Flutter 代碼還需要深入學習。但相信理解之后再學,會輕松很多。
hello world例子
在終端打印字符串‘Hello World!’
計算斐波那契數列
一個簡單的類
計算兩點距離
異步并發示例
使用了Isolate
1.面向對象
對于面向對象這個概念,相信了解Java的同學對這個概念一定不會陌生。
例如:我們有個Person Object他有很多特征和行為。
這些都是這個Person Object的屬性。
也就是因為有了這些特征,行為等等才決定了這個人是誰。
那么回到Dart當中,所有的都是對象,那么在就可以可以跟進對象的屬性的特征,方法等等來進行編程。
之所以我們在這里又特別強調了一下面向對象的概念,是因為這個概念在Dart語言當中,至關重要!
2.最重要的幾個概念
3.Dart的部分特性
4.Dart的內置庫
包名
描述
dart:asynv
異步編程,提供Future,Stream類
dart:collection
集合
dart:convert
不同類型的字符編碼解碼
dart:core
Dart語言核心功能,內置類型
dart:html
網頁開發用到的庫
dart:io
文件讀寫,IO相關
dart:math
數字常量以及函數,隨機算法等
dart:svg
事件和動畫矢量圖支持
綜上述所說要想學Flutter,先學Dart!關于Flutter下篇我會講到。為什么離不開dart!
有關更多面經、核心技術筆記;自己也是從事Android開發5年有余了;整理了一些Android開發技術核心筆記和面經題綱, 如有需要的同學請私信我回復“核心筆記”或“面試”領取!
手機APP制作流程:無需技術,教你制作一個自己的手機APP
一款手機APP的制作,說復雜非常復雜,涉及到多個領域的研發,稍復雜一點的個人研發基本上搞不定,但是,也有非常簡單的手機APP一站式制作運營方法。
隨著移動互聯網基層開開發技術的發展,無需編程技術,也可以在應用公園制作手機。這里就以應用公園為例,教您熟悉手機APP制作流程,手把手教你制作一款自己心儀的手機APP。
第一步:了解自己想要制作一款怎么的手機APP。是軟硬件結合? 游戲 類?商城類?新聞資訊類?互動類?聊天類?還是團購類、同城服務類?送餐類?企業展示類?
每一個類別的APP開發差異非常大,主要就是不同類型所需要的功能支持。對自己想要做的APP有個大致的了解,但是這一步很多人都沒搞清楚,大部分人都存在一個大概模糊的創意、想法階段。
第二步:了解自己想要做的APP的基礎功能,劃分板塊。
對基礎功能的了解、板塊的分類,上手最快的方法就是:查看市場上類似的APP進行借鑒。
第三步:界面及交互的設計
界面及交互的設計,可以直接使用“墨刀”。可以先設計一個大概,后期不斷豐富。
第四步:APP功能的開發制作
APP功能的開發直接使用應用公園就可以了。應用公園把市場上常見的APP功能進行拆分組合,你不需要懂任何編程技術,只需喲安把需要的功能挑選出,組合搭配一個,就能迅速組建出一個手機APP。
手機APP制作具體流程:
1、打開應用公園的官網,點擊“開始制作”,注冊登錄;
2、應用公園為在線APP制作平臺,所以不需要下載任何東西,直接進入制作頁面就可以;
3、應用公園目前有兩種模式:
(1)主題模式:應用公園平臺上,已經很多已經制作完善的手機APP軟件,可以直接當做模板使用,僅需要把里面的文字圖片進行替換,就可以快速制作一款APP。
(2)自由模式:就像拼圖一樣,把需要的功能自由組合搭配一下,就可以創造一款獨一無二的手機APP。
每一個功能控件的具體功能,都通過后臺自動配置。
4、手機APP打包
制作完善后,在應用公園平臺直接點擊制作完成,就會自動打包成手機安裝程序。
5、應用發布上架
在應用公園平臺直接申請應用發布,通過聯網后,就可以聯網使用了。
6、下載管理、運營
應用公園提供運營管理后臺、下載站點、下載二維碼、手機管理助手等APP相關產品,一站式服務,自動配置,免去多次開發成本,而且后期的功能、內容的更新迭代自己既可以搞定,也不需要具體的編程技術。
自己制作app需要 編程知識 。但依靠第三方工具,三分鐘就可以做成專屬自己的APP。下面以簡易網為例演示:
簡網APP工廠三大特點
1、最低的成本:節省所有開發成本,以及僅幾分鐘的時間成本。
2、實用的功能:貼近傳統網站的內容編輯與發布方式。
3、靈活的運營:生成APP后,一個人也可以完美運營。
先來了解一下APP工廠:三分鐘制作APP
使用簡網APP工廠之前,我曾經通過其他類似的APP公司制作過兩三個不同版本的免費APP,簡網的操作流程是制作門檻最低的一家。
不支持用戶名注冊,需要使用微博賬號
新浪與騰訊微博用戶數幾乎覆蓋全網網民數,我們默認用戶已經擁有微博賬號,以便于進行APP快速創建。
填寫APP信息:幾分鐘搞定
制作APP之前我們需要做一些準備工作,比如我們要明確我們要做一個怎樣的APP,我們要為這個APP準備一張1024x1024的ICON以及一張114x114的小圖標,另外還需要一張640x1136的開機圖。
從簡網APP工廠的首頁,經過3次跳轉,省略了網站注冊過程,通過模板挑選完成APP美工定案,所需的是APP的圖標與應用簡介。全過程幾分鐘足矣。
快捷實用的后臺采編系統
我們制作了一個新聞資訊類的APP軟件,同時我們擁有了一個功能齊全的后臺更新系統。利用后臺可以完全解決APP內容更新問題,可以快速進行新聞發布,包括文字、圖片、視頻、微博等形式,并且引入了完善的評論系統與社區系統。
筆者至今使用過三家大型網站的后臺系統,由于種種 歷史 原因,這些后臺系統都存在或多或少的不合理設計,也許是因為承載的功能過多,數據架構過于復雜,在新入職人員上手操作時,需要經過長時間的熟悉過程。
簡網為我們制作的APP提供了統一的后臺模板,這個后臺的功能亮點在于不僅提供原始錄入,還提供也許是目前設計最為合理的網絡來源抓取功能。包括網頁、微博在內的網絡內容,都可以在大約1分鐘時間內導入后臺中,并且實時呈現在用戶手機上的APP客戶端。
APP的生成時間約為三分鐘,APP容量只有3M,一般的寬帶都可以在1分鐘之內下載好裝進手機
我們得到了一個可安裝的APP軟件
同時獲得了一個功能完善的編輯后臺
快速的內容抓取,讓后臺采編人員的數量可以降到最低,維持一個日更新量在100篇文章左右的APP客戶端,一個工作人員足矣。
內容采編神器:發布到應用
“發布到應用”這個功能可以說是管理后臺提供的最強大的一個功能,經過簡單的設置后,我們可以在幾秒鐘之內把網絡內容發布到我們的APP客戶端。
這樣一個媒體類APP就做好了。
很高興回答這個問題。
我是從事安卓App開發的,開發過很多App,那么App是如何制作的。
頁面設計
我們看到的app都一個個頁面,每個頁面功能不同。首先是產品經理通過調研整理需求,然后將需求整理成頁面(可以使用墨刀等網頁制作),然后在交給UI人員進行專業設計和美化,最后將設計圖打包給開發人員。
開發設計
拿安卓舉例,開發使用語言也分幾種,具體得根據實際情況來選擇。
1.原生開發
安卓一般使用java語言開發,當然現在也有kotlin語言進行開發。如何開發就涉及到具體編程了,這里就不詳說了。簡單描述就是使用安卓提供的一系列控件來實現頁面,復雜點的頁面可以通過自定義控件來實現。
2.使用H5語言開發
使用H5開發的好處有很多,可以多端復用,比如瀏覽器端,ios端,當然H5開發的體驗是沒有原生好的。結合我做過的項目來說,一般是這個頁面需要分享出去的話,就用H5開發。
3.使用flutter開發
flutter是近年來谷歌推出的一款UI框架,
使用dart語言進行開發,支持跨平臺,weight渲染直接操作硬件層,體驗可媲美原生。但是flutter技術比較新,生態還不完善,開發起來效率相對偏低
頁面數據填充
頁面開發出來只是空殼子,沒有數據填充,這時候就需要通過接口獲取數據,然后解析數據,顯示在頁面上。
到此,一個大概的App制作流程就結束了。
首先你要清楚自己想要什么樣的APP,是做哪一方便的?簡單的?還是復雜的
一下我就分為兩類進行回答
一,簡單APP
必要崗位
ui設計師(至少一個)
主要負責APP頁面的搭建和交互的梳理
客戶端開發人員(至少一個)
目前市面上的APP開發方式多為混合開發,如果做一個簡單的APP可以選擇webapp,這樣不但可以減少開發周期還可以控制開發成本
服務端開發(至少一個)
目前服務器語言很多php,java,
node.js
非必要崗位
首先 ,我說的非必要崗位不是說這些崗位不重要,而是說在為了減少成本的情況下,這樣崗位可以被別的崗位所替代
產品經理
如果開發的App功能簡單,UI設計師就可以擔任這樣職責
測試工程師
當然,在時間允許的情況下,開發人員也可以是測試人員
二,復雜APP
復雜app可以考慮純原生開發,那么客戶端至少兩個人進行開發(安卓,IOS),或者考慮混合開發,及web前端+原生開發人員
必要崗位
ui設計師,安卓開發工程師,ios開發工程師,后端開發工程師,產品經理,測試工程師,人員的多少可以根據項目的大小來定
三,必要成本
服務器 :這是開發app必須要的,也就是我們放代碼的地方
上架審核所需費用 :比如IOS上架審核的花好幾百,安卓要申請軟著等
今年六月的時候,萌生了開發一個記賬 App 的想法,想去用自己的 App 記賬,管理收支。那時正好在英國是考試周,放假后,我回到了國內,準備去實現我的計劃。沒想到這暑假很快就結束了,在這個暑假中經歷的太多的事,準備了要去美國讀研的考試,遇到了生命中的另一半,同時,也將 Costuary for iPhone 帶到了這個世界。
Logo
說道為什么要開發這樣一個 App ,因為筆者在 UK 讀書,市面上很少有記賬 App 能夠實現實時匯率的換算,帶有這個功能的 App 也是操作繁雜。所以要自己開發一個,功能并沒有那么復雜的,并且能夠滿足自己在國外和國內生活需求的 App,所以自己編寫了 iPhone 的客戶端,為了獲取匯率和 Excel 導出,又用 Java 設計和編寫了 Costuary 的后端服務器。
比起今年年初開發的 Flat Weather,這個項目的代碼量大約是他的十倍,需要實現眾多的功能和模塊。
這篇文章將會介紹一下 Costuary 的功能與我開發過程中的一些心得。
效果圖設計
說到設計,兩年前,我還是一個 Android 開發者,Google 的 Material Design 是我的最愛,所以,Costuary 采用了 Android 5.0 之后采用的 Material Design 設計。其中摻雜了一些我自己的設計,因為 Material Design 的控件有時候操作繁瑣。
早在 5 月份的時候已經零零總總的用 Sketch 畫出了這個產品的 UI 和圖標,之后開始了漫長開發的過程。
Sketch交互
與去年開發的 Android 版不同,iPhone 版的 Costuary 采用了底部導航欄的設計,相比于 Android 通常使用的 Navigation Drawer 的抽屜布局,底部導航欄的設計即使在右手操作 iPhone 的時候都不會太費力。
UX功能 Features
Costuary 支持世界上主要貨幣的實時匯率轉換,所有外匯在統計時會轉換成主貨幣的數目,方便查看花銷。
日歷視圖能夠很直觀的反映出哪一天有消費和收入。
說到記賬軟件,量化消費的圖表無疑是重要的一環,Costuary 提供了餅狀圖來視覺化一段時間的花銷。
可以建立多個賬戶來表示自己的銀行卡,支付寶,現金等等。
可以看出本月的預算還有多少。
如果想要進行更加詳細的分析,可以使用導出功能將賬本導出到 Excel。
允許備份賬本內容到 iCloud。
開發
去把一紙設計變成真正的產品,這是一個獨立開發者應該具有的能力。只會寫代碼不只是我唯一掌握的,能夠去設計出來自己想要的應用并且將他實現才是我在做的事情。
這款應用的開發并沒有想象中的簡單,需要自己去實現大量 Android UI 控件,很多圓角,陰影,字體,要慢慢的去調整,讓控件適合 iPhone 的屏幕。整個應用的背后有 3 個關系型數據庫來儲存賬戶,賬本與各種匯率。與以前開發的 Flat Weather 不同,Costuary 會產生大量的用戶數據,所以整個軟件架構的穩定性變得異常重要,需要設計一些機制來防止數據丟失與損壞。
Development
為了實現 App 獲取每日的匯率,并且在 iPhone 上能夠實現賬本導出到 Excel ,我設計了一個服務器后端來處理這些繁雜的實物。每次 App 啟動后會與我的服務器來更新最新的匯率。當用戶選擇導出時,賬本會被發送到服務器上并處理為 Excel 發送到用戶的郵箱里。
說到服務器,就不得不提到用戶隱私了,因為導出到 Excel 功能需要將賬本傳到我的服務器上做進一步處理,很多人會覺得我侵犯了他的個人隱私。對此,為了保護我的權益與用戶的權益,我撰寫了 Costuary 軟件許可及服務協議與 Costuary 隱私政策,這是我作為獨立開發者這么多年后第一次去寫許可協議。
Agreement資費
與我的其他產品一樣,這款 App 依舊是免費供大家使用的,作為獨立開發者,我們都知道,絕大多數用戶不會去珍惜一個免費的產品。就像 Flat Weather 一樣,雖然獲得了很多人的支持,但是也收到了很多人的吐槽。在 Costuary 中依然設計了一個的捐助按鈕,如果大家使用之后喜歡這個應用,請支持我將他維護下去。
Please donate me尾巴
Costuary for iPhone 是我開發出來過最大的軟件體系。我相信,能夠獨立開發出來產品的人懂得不只是編程。一個人要去經歷項目的全部生命周期:規劃,設計,開發,運營,維護,營銷,這些是我開發這么多產品所學會的。
現在的 Costuary 只是第一個版本,還有很多 iPhone 的特性沒有來得及開發,以后會跟上的,比如 iPhone X 的適配,3D Touch、Today Widget、Touch ID 等等。
以前在少數派撰稿的時候,很多讀者會來問我如何學習開發,我也特地去寫過如何去學習編程,但我相信,真正想去學習的,想去為這個生態貢獻出自己的一份力的人,自己都會找到學習的方法。我的專業是電子電器而不是軟件工程,但是我不后悔當年去學習編程。
最后,還是感謝在背后默默支持我的人,我會不斷地改進與提升,如果 Costuary 真的在記賬方面給予了你便利,這是我莫大的榮幸。
如果想要了解我的更多作品可以訪問我的個人博客 MikeTech,或者在少數派中閱讀我以前寫過的文章。今年年初也在 iPhone 上寫過一個天氣 App,天氣應用 Flat Weather 的設計歷程
對了,關于記賬有什么用,如何記賬,如何養成記賬的習慣。為什么每個月末都捉襟見肘,除了沒錢,很可能是對財務管理的能力不強。想了解這一方面的知識,不妨看一看我派的付費閱讀欄目:從零開始做好個人記賬
你好,非常感謝你的邀請。
開發一個app的話首先
第一步、需要調研,分析開發需求。
第二步、根據你的開發需求整理一個開發方案,選擇合理的架構。
第三步、開始研發。
第四步、測試。
第五步、上線試運行。
第六步、查缺補漏后投入使用。
開發一個app的話。有多種選擇。可以找一個第三方公司來進行開發。也可以自己招聘開發團隊。也可以交給比較信任的程序員朋友來進行開發。第三種方式的話,屬于接私活兒,成本較低。 當然前提你得有認識的人。
我也是程序員出身。參與過web網站開發。傳統辦公開發。H5開發。微信小程序開發。以及安卓開發。有著較豐富的開發經驗。自己完全可以勝任一個App,如果你有這方面的事需求的話,也可以私信我。我是山東的。如果方便的話也可以面談。
App軟件開發,從之前的溝通需求、規劃設計、程序開發、測試修改、它的發布等。這是一個非常復雜和漫長的過程,一旦進入通信,就需要定期維護和功能變更。它需要大量的專業人員參與,成本自然很高。 所以,隨著更新市場的發展和人們福利的提高,現在已經不像傳統開發那么困難了。只需要動動鼠標,不需要觸碰代碼就可以完成制作app部分。
App開發已成為企業發展的重要推動力量
十年巨變!移動互聯網已顛覆我們的時代,商業、社交、視頻、新聞、工具等領域,移動應用的滲透率已高達95%,在團購 旅游 和零售行業,移動端收入規模已超過PC端,手機APP已成為企業不可或缺的線上陣地。
不用編程就能制作app的在線平臺,擺脫了很多復雜的流程,還能減少用戶的麻煩,不會制作,而且可以在平臺上查看詳細的課程,非常貼心的設置!在這里,我想說的是,如果你想制作app的話,可以在平臺上查看詳細的課程。總的來說,這種方法會大大降低軟件開發app的成本,節省時間,讓很多人解決了資金短缺和想快速制作app的問題。
app是如何制作的,APP如何開發?
隨著智能手機APP軟件的吸引力越來越大,越來越多的企業開始開發自己的APP應用。企業要想開發屬于自己企業的APP應用,首先要分析自身的情況和市場對產品的需求。
在APP,開發這件事上,企業一定要注意以下幾點。
1. 開發APP應用一定要明確以自己為中心,開發APP是否能帶來巨大的利潤。
2. 要了解目標用戶的需求,配置APP吸引用戶,提高用戶購買應用的意愿。
3. 通過合作再次尋找潛在客戶,我相信開發APP的收益遠遠大于成本。
開發APP蘋果系統,必須使用Xcode蘋果開發工具,一般采用Objective-C或Swift語言。Objective-C是繼承了C語言的C字,可以直接用Objective-C語言進行編程。如果你不懂數據,差別很小。還有一些新的蘋果后綴語言,非常有用。
Andro系統的app都是用Java語言開發的,Java語言已經流行了20多年,這個趨勢還在持續和延續。如果想要安卓系統的app首先要掌握Java語言,對于說C語言的人來說,學習Java還是很容易的。如果你對自學感興趣,Java網站上有很多培訓課程,還有很多免費培訓。視頻,不想付費。如果這個絕對是零基礎(沒學過其他編程語言,比如c語言),如果真的很感興趣,可以自學,但是速度比較慢。
總結:app開發擁有多種方法,選擇最適合自己的方式方法很重要
答案寫到這里,我想您應該知道了app的開發途徑或者方法是什么。如果您是小企業或者是個體工商戶,您可以找人幫忙開發小程序或者自己在一些網站上進行傻瓜式軟件開發。正如上文所說,現在有很多的網站支持在線生成APP,常用的功能和接口都已經設置好了,操作起來不是很難。如果您是大企業,業務多訪問量比較大,我的建議是您應該聘請專業的軟件工程師開發專門的app,避免后期出現的問題沒辦法及時解決給您的企業帶來損失。
不懂的話,找專業的人幫忙,我就是專業的
app即application program。應用程序。目前手機平臺是ios和安卓兩大平臺的天下。本人不才從事安卓開發。簡單介紹一下吧你問的這個問題范圍太廣。ios和安卓開發語言不同。ios使用的是object_c和swift。安卓是基于java。二者都屬于面向對象的語言。開發平臺安卓基于android studio早期使用的是eclipse+adt。不過已經被淘汰了。那么怎樣開發app?首先你需要一個后臺程序員寫服務器以及搭建數據庫。其次你的會ios或是android其中之一那么這就是最簡單的配置.現在流行混合開發如果你再會點前端的h5和js就更好了。一般一個軟件公司的基本配置是一個前端一個ios一個安卓一個后臺。基本就滿足你搭建網站和手機應用的需求了。不過你作為老板養這樣一個團隊很費錢。還不如找外包
軟件的生成需要經歷以下幾個階段:
1、滿足用戶需求——建立軟件目標,設想產品功能,進行場景化細分說明;進行可行性分析,用戶需求收集,用戶需求場景描述;場景問題梳理;獲取用戶行為、想法;場景應用痛點,機會點
2、需求開發與管理——建立用戶畫像,從軟件目標出發,進行問題梳理,場景行為分析,愿景分析,建立體驗地圖
3、利用Axure繪制軟件原型,在用戶場景中切入,并組織軟件原型實施,在實施過程中進行問卷調查,收集問題,記錄用戶行為,不斷改善軟件需求,進行需求評審,進入評審優化
4、技術可行性分析——技術分析,場景分析,功能實現驗證,
5、開發計劃制定,實施,測試,驗證,發布
在Tree中從上往下高效傳遞數據的基類widget , 定義為:abstract class InheritedWidget extends ProxyWidget
Flutter的響應式開發與React類似,數據都是自頂向下的。
假設有祖先組點A,中間經過結點B, C,然后到結點D,D需要從A中獲取數據f,那按照自頂向下數據流轉,f需要依次傳遞給B及C,最后才到C。這樣開發極為不靈活,成本也比較高。所有Flutter需要有跨結點(只能是祖先后代節點,不能跨兄弟節點)高效傳遞數據的方案。
大體意思如下:
InheritedWidget 是在樹中高效向下傳遞信息的基類部件;
調用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例;
在 InheritedWidget 類型的控件被引用,也就是調用過 inheritFromWidgetOfExactType 方法后,當 InheritedWidget 自身狀態改變時,會導致引用了 InheritedWidget 類型的子控件重構(rebuild)。
這里隨便定義一個人 Person 類。
創建一個類繼承 InheritedWidget,并實現 updateShouldNotify 方法。
之前說到調用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例,所以此處定義一個靜態的 of 方法,通過傳入的 context 獲取到最近的 InheriedDataWidget 實例。
1.定義數據模型
這里隨便定義一個 Person 類。
2.自定義 InheritedWidget 控件類
創建一個類繼承 InheritedWidget,并實現 updateShouldNotify 方法。
之前說到調用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例,所以此處定義一個靜態的 of 方法,通過傳入的 context 獲取到最近的 InheriedDataWidget 實例。
3.InheriedDataWidget 的使用
InheriedDataWidget 使用起來也很簡單,它本身也是一個控件,只要在任意一個頁面的子控件調用其構造方法就行,這里我們定義一個形如的 Widget 樹。
WidgetA 是一個 StatefulWidget 類型的控件,可以調用 setState 刷新,如果是繼承人 Stateless 類型的控件,那我們也可以通過 Stream 或者其他方式刷新數據,感興趣的請看[什么是 Stream? Dart
WidgetA1_1 類
WidgetA1_2 類
WidgetA1_3 類
當我們點擊 floatingActionButton 的時候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都會更新 Person 的信息,而且每點 floatingActionButton 一次, 當我們點擊 floatingActionButton 的時候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都會更新 Person 的信息,而且每點 floatingActionButton 一次,都會輸出:
如果我們試圖在和 WidgetA 的同一層級的兄弟節點去訪問 InheriedDataWidget 的 Person 數據,是不行的,因為父節點中并沒有插入 InheriedDataWidget。
把 WidgetB 和 WidgetA 保持同一節點
這也體現了 Inheried(遺傳) 這一單詞的特性,遺傳只存在于父子。兄弟不存在遺傳的關系。
這種數據共享的方式在某些場景還是很有用的,就比如說全局主題,字體大小,字體顏色的變更,只要在 App 根層級共享出這些配置數據,然后在觸發數據改變之后,所有引用到這些共享數據的地方都會刷新,這換主題,字體是不是就很輕松,事實上 Theme.of(context).primaryColor 之流就是這么干的。
以上就是有關InheritedWidget的使用。
自己也是從事Android開發5年有余了;整理了一些Android開發技術核心筆記和面經題綱,有關更多Android開發進階技術資料、面經題綱、核心技術筆記; 想要進階自己、拿高薪的同學請私信我回復“核心筆記”或“面試”領取!