新聞中心
Flutter 之 文件操作(二十九)
Dart的 IO 庫(kù)包含了文件讀寫的相關(guān)類,它屬于 Dart 語(yǔ)法標(biāo)準(zhǔn)的一部分,所以通過 Dart IO 庫(kù),無論是 Dart VM 下的腳本還是 Flutter,都是通過 Dart IO 庫(kù)來操作文件的,不過和 Dart VM 相比,F(xiàn)lutter 有一個(gè)重要差異是文件系統(tǒng)路徑不同,這是因?yàn)镈art VM 是運(yùn)行在 PC 或服務(wù)器操作系統(tǒng)下,而 Flutter 是運(yùn)行在移動(dòng)操作系統(tǒng)中,他們的文件系統(tǒng)會(huì)有一些差異。
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出霞山免費(fèi)做網(wǎng)站回饋大家。
Android 和 iOS 的應(yīng)用存儲(chǔ)目錄不同, PathProvider 插件提供了一種平臺(tái)透明的方式來訪問設(shè)備文件系統(tǒng)上的常用位置。該類當(dāng)前支持訪問兩個(gè)文件系統(tǒng)位置:
File代表一個(gè)整體的文件,他有三個(gè)構(gòu)造函數(shù),分別是:
文件讀取本身有兩種形式,一種是文本,一種是二進(jìn)制。
2.2.1 讀取文本內(nèi)容
如果是文本文件,F(xiàn)ile提供了readAsString、readAsLines、readAsStringSync、readAsLinesSync方法,讀取文本內(nèi)容
readAsString 一次性讀取所有文本
readAsLines 一行行的讀取文本
結(jié)果返回的是一個(gè)List,list中表示文件每行的內(nèi)容
readAsStringSync、readAsLinesSync同步讀取文本
2.2.2 讀取二進(jìn)制內(nèi)容
如果文件是二進(jìn)制,那么可以使用readAsBytes或者同步的方法readAsBytesSync:
dart中表示二進(jìn)制有一個(gè)專門的類型叫做Uint8List,他實(shí)際上表示的是一個(gè)int的List。
上面提到的讀取方式,都是一次性讀取整個(gè)文件,缺點(diǎn)就是如果文件太大的話,可能造成內(nèi)存空間的壓力。
所以File為我們提供了另外一種讀取文件的方法,流的形式來讀取文件.
示例
dart提供了open和openSync兩個(gè)方法來進(jìn)行隨機(jī)文件讀寫:
寫入和文件讀取一樣,可以一次性寫入或者獲得一個(gè)寫入句柄,然后再寫入。
一次性寫入的方法有四種,分別對(duì)應(yīng)字符串和二進(jìn)制
句柄形式可以調(diào)用openWrite方法,返回一個(gè)IOSink對(duì)象,然后通過這個(gè)對(duì)象進(jìn)行寫入:
默認(rèn)情況下寫入是會(huì)覆蓋整個(gè)文件的,但是可以通過下面的方式來更改寫入模式:
雖然dart中所有的異常都是運(yùn)行時(shí)異常,但是和java一樣,要想手動(dòng)處理文件讀寫中的異常,則可以使用try,catch:
我們還是以計(jì)數(shù)器為例,實(shí)現(xiàn)在應(yīng)用退出重啟后可以恢復(fù)點(diǎn)擊次數(shù)。 這里,我們使用文件來保存數(shù)據(jù):
1.引入PathProvider插件;在pubspec.yaml文件中添加如下聲明:
執(zhí)行 flutter pub get
2.實(shí)現(xiàn)如下
參考:
Flutter 報(bào)錯(cuò) zsh: command not found: flutter
flutter的命令失效, 提示 zsh: command not found: flutter
解決辦法:
1 、執(zhí)行:【open ~/.zshrc 】
2、如果 提示文件不存在,則執(zhí)行:【vim ~/.zshrc 】新建一個(gè)新文件
3、新建窗口再執(zhí)行【open ~/.bash_profile 】
4、把 打開的bash_profile 中的內(nèi)容copy到 上一個(gè)窗口新建的zshrc 文件中,保存:
【:wq回車】
5、再使用source命令重新加載一下:【source ~/.zshrc】,下次再編輯這個(gè)文件就可以直接執(zhí)行:【open ~/.zshrc】
6、運(yùn)行【flutter -h 】看是否生效
Flutter初始化
新建一個(gè)Flutter工程,android模塊。
1,只有一個(gè)Activity組件,它是Dart層繪制Widget的容器。
2,Application配置FlutterApplication。
應(yīng)用Application配置io.flutter.app.FlutterApplication類,App首次啟動(dòng)時(shí),初始化。
調(diào)用FlutterMain.startInitialization()方法。
initConfig方法,從AndroidManfest.xml配置的applicaion節(jié)點(diǎn)獲取meta-data數(shù)據(jù),初始化以下默認(rèn)值。
這些值都是使用中用到的name,例如,抽取apk中asset資源時(shí),flutter_assets打包目錄,打包產(chǎn)物data名稱。
initResources方法, 初始化資源。
在Flutter打包apk的asset目錄下,包括fluttter_asset目錄/資源項(xiàng),將資源從apk中抽取,保存在 Context.getDir("flutter", 0) 目錄下。
/data/user/0/包名/app_flutter目錄。
在目錄中創(chuàng)建一個(gè)時(shí)間戳文件,根據(jù)apk版本和包信息記錄的lastUpdateTime更新時(shí)間,第二次啟動(dòng)時(shí),若apk未更新,不需要再次抽取。
加載so庫(kù),libflutter.so,System.loadLibrary()。
主頁(yè)面繼承FlutterActivity,配置啟動(dòng)模式singleTop。
FlutterActivity類在io.flutter.app包, (區(qū)別io.flutter.embedding.android包), 組件生命周期委托給FlutterActivityDelegate類。
組件啟動(dòng),onCreate方法。
FlutterMain.ensureInitializationComplete方法,確保資源成功抽取完成,創(chuàng)建FlutterView視圖(io.flutter.view),繼承SurfaceView類,setContentView方法,設(shè)置組件主布局即FlutterView視圖。
最后,根據(jù)Bundle路徑,runBundle()加載運(yùn)行,
調(diào)用FlutterView的runFromBundle方法,入口點(diǎn)在dart的main方法,
通過FlutterNativeView,調(diào)用FlutterJNI的native方法。
nativeRunBundleAndSnapshotFromLibrary方法。
任重而道遠(yuǎn)
iOS開發(fā)Flutter探索-State狀態(tài)保存(10)
有時(shí)候我們不希望某個(gè)頁(yè)面每次打開時(shí)都重新加載,比如就我們之前的Tabbar結(jié)構(gòu)的頁(yè)面,每當(dāng)我們?cè)谇袚QTab的時(shí)候都會(huì)執(zhí)行 void initState() ,這就意味著頁(yè)面每次都會(huì)重新渲染,之所以這樣就是因?yàn)槲覀兊?State 狀態(tài)沒有保存,如下圖所示:
[沒有狀態(tài)保存效果圖]
給當(dāng)前 State 類添加一個(gè)擴(kuò)展(這里就用擴(kuò)展這個(gè)詞吧,其實(shí)類似于iOS下的 Category ),一個(gè)系統(tǒng)的擴(kuò)展類 AutomaticKeepAliveClientMixin ,并重寫 wantKeepAlive 方法,讓一個(gè)普通的 State 類,具有保存狀態(tài)的能力。
在Dart語(yǔ)法中通過使用 with 關(guān)鍵字來添加擴(kuò)展:
bool get wantKeepAlive = true; 之后,當(dāng)前 State 就具備保存能力了,也就意味著重復(fù)切換Tab后, void initState() 就不會(huì)重復(fù)執(zhí)行了(由原來的 viewWillAppear() 變成了 viewDidLoad() )。
按照上面方式修改后,發(fā)現(xiàn)切換Tab后 void initState() 依然重復(fù)執(zhí)行了,這是為什么吶?這里我們看下我們之前 root_page.dart 里面是如何配置我們的tabbar結(jié)構(gòu)的:
這里我們是通過一個(gè) _viewControllers 的List,把4個(gè)子頁(yè)面放在了里面,全局有一個(gè) _currentIndex ,當(dāng) onTap 回調(diào)后后,更新 _currentIndex 的值,執(zhí)行 setState () 后, body 對(duì)應(yīng)的 widget 頁(yè)面發(fā)生改變。而問題也就出在這里,當(dāng) body 部分發(fā)生改變時(shí),根據(jù)Flutter的底層渲染邏輯,這里會(huì)移除掉之前的 Widget ,并重新創(chuàng)建新的 Widget ,我們之前在 _viewControllers 放的子頁(yè)面,并不像iOS下是一個(gè)實(shí)例對(duì)象,存在就直接拿來使用。在Flutter 中 setState () 后界面會(huì)被重新繪制,而 body 部分只知道我要渲染一個(gè)什么樣的 widget ,而該類型的 widget 每次都是會(huì)重新創(chuàng)建,這也就意味著我們?cè)赥ab切換時(shí),每次都是重新創(chuàng)建,所以每次都執(zhí)行了 initState() 。
顯然我們現(xiàn)在的方式是不合理的,那在Flutter中如何管理這樣的子頁(yè)面,而避免重復(fù)渲染吶?
這就要用到一個(gè)新的部件了: PageView() ,內(nèi)部的2個(gè)關(guān)鍵屬性:
子頁(yè)面切換通過 _controller.jumpToPage(index); 來實(shí)現(xiàn)。
這樣子頁(yè)面也就不會(huì)重新創(chuàng)建渲染了,我們的狀態(tài)保存也就能正常實(shí)現(xiàn)了。
學(xué)習(xí)是一個(gè)循序漸進(jìn)的過程,我們總是在踩坑中不斷的前行,把坑填平了也就意味著我們?cè)谶@個(gè)新的東西面前立了足,就可能進(jìn)行更多為什么的探索了。
Flutter開發(fā)--Pub包管理
在原生開發(fā)中, Android 使用 Gradle 來管理依賴, iOS 用 Cocoapods 來管理依賴,Node 中通過 npm來管理依賴。 Flutter 使用配置文件 pubspec.yaml (位于項(xiàng)目根目錄)來管理第三方依賴包。
Pub 是Google官方的Dart Packages倉(cāng)庫(kù),類似于node中的npm倉(cāng)庫(kù),android中的jcenter,我們可以在上面查找我們需要的包和插件,也可以向pub發(fā)布我們的包和插件。
Pub工具 包含管理Package、部署Package和部署命令行應(yīng)用的命令。
如果使用的是Flutter SDK,不要直接使用pub命令。而是使用flutter pub命令,如下:
命令pub get/upgrade/outdated 屬于管理Package的依賴關(guān)系
用于檢索當(dāng)前 Package 所依賴的其它 Package。如果 pubspec.lock 文件已經(jīng)存在,則根據(jù)該文件中保存的依賴項(xiàng)版本獲取對(duì)應(yīng)的依賴項(xiàng)。如有必要,將會(huì)創(chuàng)建或更新該文件。
更新 package 依賴
當(dāng)你添加一個(gè) package 后首次運(yùn)行 flutter pub get, Flutter 將會(huì)保存在 pubspec.lock lockfile 中找到的具體 package 版本。這將確保當(dāng)你或者團(tuán)隊(duì)中其他開發(fā)者運(yùn)行 flutter pub get 后能得到相同版本的 package。
如果你想升級(jí)到 package 的最新版本,比如使用 package 的最新特性,請(qǐng)運(yùn)行 flutter pub upgrade 。這將檢索你在 pubspec.yaml 文件中指定的版本約束所允許的最高可用版本。
案例
在flutter項(xiàng)目中導(dǎo)入hive包,在pubspec.yaml文件中添加配置:
執(zhí)行flutter pub get,可以在 pubspec.lock 中看到 hive 版本是2.1.0,這是因?yàn)槟壳癶ive的最新版本是2.1.0,配置“^”表示向最新版本兼容,具體可查看Package版本管理( ),所以再執(zhí)行flutter pub upgrade 可以看到版本還是2.1.0,這個(gè)時(shí)候會(huì)發(fā)現(xiàn)pub get和 pub upgrade 效果一樣。
但是未來如果 hive 發(fā)布了2.2.0版本,這個(gè)時(shí)候使用flutter pub get在pubspec.lock中看到hive版本依舊是2.1.0,而執(zhí)行flutter pub upgrade 后在pubspec.lock中看到hive版本就是2.2.0。
現(xiàn)在先在flutter 項(xiàng)目的pubspec.yaml文件添加配置,指定hive版本是2.0.5,如下:
這個(gè)時(shí)候執(zhí)行flutter pub get后,可以在pubspec.lock的文件中看到hive版本是2.0.5,如果這個(gè)時(shí)候更改配置為 hive: ^2.0.5,再執(zhí)行flutter pub get就會(huì)發(fā)現(xiàn)在pubspec.lock的文件中看到hive版本還是2.0.5,這個(gè)時(shí)候可以執(zhí)行flutter pub outdated查看依賴的每個(gè) package,如下圖,
可以看到,Upgrable項(xiàng)hive版本號(hào)為2.1.0,執(zhí)行flutter pub upgrade 后可以看到在pubspec.lock的文件中看到hive版本是2.1.0
在pubspec.yaml文件添加配置:
lxx_package_demo信息如下圖:
執(zhí)行flutter pub get后在pubspec.lock中看到flutter_log版本是0.0.1
現(xiàn)在修改lxx_package_demo版本號(hào)為0.0.2,再執(zhí)行flutter pub get
會(huì)發(fā)現(xiàn)版本會(huì)及時(shí)更新為0.0.2,這個(gè)時(shí)候執(zhí)行flutter pub get/upgrade效果一樣
參考文檔:
第十六章:Flutter數(shù)據(jù)存儲(chǔ)
Flutter的數(shù)據(jù)存儲(chǔ)分為三類
Preference相當(dāng)于iOS的NSUserDefaults,其實(shí)也是按plist的方式存儲(chǔ)的
step1:添加依賴
step2:pub get
step3:導(dǎo)入頭文件
在path_provider中有三個(gè)獲取文件路徑的方法:
- getTemporaryDirectory()
://獲取應(yīng)用緩存目錄,等同iOS的NSTemporaryDirectory()和Android的getCacheDir() 方法。
- getApplicationDocumentsDirectory():
//獲取應(yīng)用文件目錄類似于iOS的NSDocumentDirectory和Android上的 AppData目錄。
step1:添加依賴
step2:pub get
step3:導(dǎo)入頭文件
網(wǎng)站名稱:flutter保存,flutter保存pdf
文章來源:http://ef60e0e.cn/article/dsgsscj.html