Weather: Rain - cloudy

Zero, preface,

For those who ask me how to study, it’s chicken soup, which I don’t like to drink or cook.

In this paper, according to the actual situation, share some personal programming experience, their own reference, learn from each other


1. Asynchronous operation under the single thread model

  • Why do you emphasize yes?Single threadDart is a single threaded model, single threaded model, single threaded model!!

What’s asynchronous: You need to boil water (time-consuming operation), but you don’t have to wait for the water to boil before you can do the next thing (sweeping the floor)

Just fire (method call), and then you can sweep the floor (perform the method below the asynchronous task), boil the water (callback), and flush the water (process the result of the asynchronous task).

  • Dart asynchronous programming: Future and Stream

A “Future” is the equivalent of a 40m machete and a “Stream” is a bundle of 40m machetes

Dart provides the keywords async and await, which are just plain handy little daggers


1.asyncandawaitSimple use of

It feels like there are tutorials on the Internet that tell you what’s wrong and then take steps to correct it… There is no complete code summary at the end

I think we should at least give a proper demonstration… And then the error case

1.1: The simplest file read
ReadFile (name) {var file = file (name); return file.readAsString(); } readOk() async{var result = await readFile(r"C:\Users\Administrator\Desktop\ long.txt "); print(result); } main() { readOk(); Print (" What number am I?" ); }Copy the code

Function execution saw async (water) to perform the following operation will be (), water to boil, await release print (result); (water)


1.2.asyncandawaitThe analysis of the

You might ask, what if we don’t have async or await? What happens if you don’t add them?

No async or await: Execute sequentially as normal code. Add async without await: However, there is no use. No async with await: Error


2. Go get my 40m machete:Future

File.readasstring () returns Future

,

Main () {var file = file (r"C:\Users\Administrator\Desktop\ long.txt "); Future<String> re = file.readAsString(); re.then((result) { print(result); }); Print (" What number am I?" ); }Copy the code

This operation can also achieve asynchronous effect, the specific will not go into detail

I plan to write one sometime: a comprehensive discussion of single-threaded, multi-threaded, synchronous, and asynchronous based on Java,Python,JavaScript(ES6+),Dart, and Node (all of which I’ve covered before). After all, those words really bother me


I/O operations in Dart

1. API test for file operationThe constructor

File.fromuri (Uri resource path identifier) file.fromRawPath (Uint8List rawPath)Copy the code

How to recognize a class:Uri as an example

Maybe you’ll see file.fromuri (Uri Uri) and say, “I don’t know Uri,” and leave it at that. It won’t hurt to take a look if you have time

My rule of thumb is to look at the constructor first, then look at the fields, then look at the method names (Ctr+F12). If you don’t know anything about the class, look at the documentation first, at least for those who know what it is, there is usually a brief sentence about it. Android has some understanding of URIs as a resource location marker, like a house number.

-- -- -- - > [comments first sentence] -- -- -- -- -- -- -- -- -- -- -- -- A parsed URI, to as A URL. The URL, we all know: http://192.168.43.60:8089/file/springboot/data.json -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - It is composed of a part: HTTP (agreement) : / / + 192.168.43.60 (domain name) + : 8089 (port) + file/springboot/data. The json resource (address) such as resources, I am I: you are looking for China: / / anhui: Hefei/yao village road/sea/XXX XXX/packer jet strong -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > / Uri of the core attribute -- -- -- -- -- -- -- -- -- -- -- -- the factory  Uri( {String scheme, String userInfo, String host, int port, String path, Iterable<String> pathSegments, String query, Map<String, dynamic /*String|Iterable<String>*/ > queryParameters, String fragment})Copy the code
I don’t know what to try, anyway, it is free to run
var base = Uri.base; print(base); / / print with path - file:///I:/Java/Android/FlutterUnit/toly/ -- -- -- -- -- > [. Parse method test] static Uri parse (String Uri, [int start = 0, Int end]) // Since uri.parse returns a Uri object, It should have corresponding properties of Uri var parse = Uri. Parse (" http://192.168.43.60:8089/file/springboot/data.json "); print("host=${parse.host}"); / / 192.168.43.60 print (" port = ${parse. Port} "); //8089 print("path=${parse.path}"); //file/springboot/data.json print("query=${parse.query}"); // print("fragment=${parse.fragment}"); // ----->[. HTTP method test] uri.http (String authority, String unencodedPath,[Map<String, String> queryParameters]) ----->[.http] ------- //Creates a new `http` URI from authority, path and query //http://example.org/path?q=dart. //new Uri.http("example.org", "/path", { "q" : "dart" });Copy the code
What happens if you open a network Uri using File:

Learn to analyze bugs and don’t deny them

Make sure the url is correct first

Var file = file. FromUri (new Uri. HTTP (" 192.168.43.60:8089 ", "/ file/springboot/data. The json")); Unhandled exception: Unsupported operation: Cannot extract a file path from a http URI #0 _Uri.toFilePath (dart:core/uri.dart:2617:7) #1 new File.fromUri (dart:io/file.dart:265:49) #2 readFile (file:///I:/Java/Android/FlutterUnit/toly/test/base/8_io.dart:11:19)Copy the code

Maybe you go, will think (of course I am also such) : what the devil, Lao Tze look for a long time, TM can not use, waste of time!

Maybe you will walk away angry, while I will analyze the reason for the mistake (this is the different choice to face the mistake). The former may never know the reason, and the latter will learn something on the way even if it doesn’t work out.


So, let’s check it out
---->[bug link:] String toFilePath({bool Windows}) {if (scheme! = "" && scheme ! = "file") { throw new UnsupportedError( "Cannot extract a file path from a $scheme URI"); } // what is scheme? Var uri = new uri. HTTP (" 192.168.43.60:8089 ", "/ file/springboot/data. The json"); print(uri.scheme); // new Uri. HTTP scheme is HTTP, but this is not file. File.fromuri () cannot access urIs that are not File types. ------- /** * Create a File object from a URI. ** If [URI] cannot reference a file this throws [UnsupportedError]. UnsupportedError */ factory file.fromuri (uri URI) => new file (URi.toFilepath ()); UnsupportedError */ factory file.fromuri (URI URI) => new file (URI.tofilepath ()); Well, didn't pay attention to at the beginning, is a mistake to this can end the wrong is not terrible, terrible is you don't know why to also make later, anyhow on pit is much, will that pit where Maybe someone said to you that have a pit, be careful of the past, for the first time, nobody remind you next time, you might fallCopy the code

What is the Uri of file?

In case you didn’t know, the file will open when you drag it into the browser, and all you see is a FEil Uri

// There are many comments on the source code. See.... * // file:///C:/xxx/yyy * new Uri.file(r"C:\xxx\yyy", windows: true); */ factory Uri.file(String path, {bool windows})Copy the code
. Then you can use the File fromUri: var File = File. FromUri (Uri. Parse (" file:///F:/SpringBootFiles/file/springboot/data.json "));Copy the code

Start with a small API and make yourself aware of as many things as you can. It doesn’t mean that you need to be clear about the source code

Within 150% of their acceptance range can try, failed is not relevant, the total than to see those refuted articles have significance

If you want to improve yourself (and this is for you) :

Don’t let yourself always walk on a smooth road. Sometimes you can only get a glimpse of the beautiful scenery by climbing high and looking far away. I am in a bad mood today, so I have a little too much nonsense. Listen to what I hear and ignore what I don’t. If you want to contradict me, please feel free to comment in the comment section!!

[End of external affairs]

2. Common apis for File and Directory

In Java, folders are also File objects, which Dart distinguishes

Interestingly, the APIS for File and Directory are basically synchronous and asynchronous pairs


2.1: Create folders recursively

By default, recursive is false and only the next level can be created

main() {
  var dir = Directory(r"C:\Users\Administrator\Desktop\dart\test\all\li");
  dir.createSync(recursive: true);
}
Copy the code

2.2: Lists all files
main() async { var dir = Directory(r"E:\Material\MyUI"); var list = dir.list(); ForEach ((fs){print(fs.path); }); }Copy the code

main() async { var dir = Directory(r"E:\Material\MyUI"); var list = dir.list(recursive: true); List. ForEach ((fs){print(fs.path); }); }Copy the code

All files in the directory are listed, no map


2.3: Rename

Just have a look

  var dir = Directory(r"C:\Users\Administrator\Desktop\dart\test\all\li");
  dir.rename(r"C:\Users\Administrator\Desktop\dart\test\all\hello");
Copy the code

3. Common operations on File objects:
ReadFile (name) async {// create file object var file = file (name); Try {// Determine whether bool exists = await file.exists(); If (exists) {// print(await file.length()); Print (await file.lastmodified ()); // Last modified time --2018-12-21 13:49:35.000 print(file.parent-path); // Get the path to the parent folder -- -c :\Users\Administrator\Desktop\dart return await file.readasString (); } else {await file.create(recursive: true); // Read the file and return} else {await file.create(recursive: true); Return "No file has been found, it has been created for you! Dart robot :2333"; }} catch (e) {// print(e); }}Copy the code

In addition, there are several different ways to open, Java basically contains, see the name also know what


4. File writing:

As in Java, default full swap: Want to append: parameter plus mode: filemode.append

Main () async {wirte(r"C:\Users\Administrator\Desktop\dart\ long.txt "); } wirte(name) async{ var file = File(name); File. WriteAsString (" On the other side of the sea there is grace I have not witnessed "); }Copy the code


Third, about the mobile terminal file reading problem

1. The path is faulty

Path_provider: ^0.4.1: Provides three paths, just use it

LocalPath () async {try {print(' temporary directory: '+ (await getTemporaryDirectory()).path); / / - / data/user / 0 / com. Toly1994. Toly/cache print (' document directory: + (await getApplicationDocumentsDirectory ()). The path). / / - / data/user / 0 / com. Toly1994. Toly/app_flutter print (' sd card catalog: + (await external.getexternalstoragedirectory ()). The path). //----/storage/emulated/0 } catch (err) { print(err); }}Copy the code

2. Dynamic permission application

Simple_permissions: ^0.1.9: provides dynamic permission application

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Copy the code
readFormSD() async { try { var perm = SimplePermissions.requestPermission(Permission.ReadExternalStorage); var sdPath = getExternalStorageDirectory(); Sdpath.then ((file) {perm.then((v) async {var res = await readFile(file.path + "/ request.txt "); print(res); }); }); } catch (err) { print(err); }}Copy the code

All right, so that’s it


3. Quiz: List the files on the SD card

Basically, it reads the contents of the folder and sets it to the Item of the ListView

import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; import 'package:simple_permissions/simple_permissions.dart'; class ListFilePage extends StatefulWidget { @override _ListFilePageState createState() => _ListFilePageState(); } class _ListFilePageState extends State<ListFilePage> with SingleTickerProviderStateMixin { List<String> _files = []; @override void initState() { super.initState(); localPath(); } @override Widget build(BuildContext context) {// create listView var listView = listView. builder(itemCount: _files.length, itemBuilder: (BuildContext context, int index) { return Column( children: <Widget>[ Container( color: Colors.white, padding: EdgeInsets.all(15), child: renderItem(index)) ], ); }); Return Scaffold(appBar: appBar (title: Text(" Scaffold "),), body: listview,); } / / adding all the SD Calvin a name localPath () {try {var perm. = SimplePermissions requestPermission (Permission. ReadExternalStorage); var sdPath = getExternalStorageDirectory(); sdPath.then((file) { perm.then((v) { file.list().forEach((i) { _files.add(i.path); }); setState(() {}); }); }); } catch (err) { print(err); }} renderItem(index) {return Row(children: <Widget>) [Icon(Icons. Extension, color: Colors.blue, ), Expanded( child: Padding( padding: EdgeInsets.only(left: 20), child: Text( _files[index], style: TextStyle(fontSize: 18), ), )), Icon(Icons.arrow_forward), Divider(height: 1) ], ); }}Copy the code

3. Network request Operations in Dart

0. Add dependencies:Under pubspec.yaml dependencies
HTTP: ^ 0.11.3 + 17Copy the code

My server provides some network request apis, if you want to build your own server interface, see this article

To review the API of the interface:

Query interface: GET request -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- all the query: http://www.toly1994.com:8089/api/android/note - 12 query migration, query 12 (that is, article 12 to a page of page 2) : http://www.toly1994.com:8089/api/android/note/12/12 - by region query (A data for Android, SB for SpringBoot data, Re the React data) http://www.toly1994.com:8089/api/android/note/area/A http://www.toly1994.com:8089/api/android/note/area/A/12/12 - click part name query http://www.toly1994.com:8089/api/android/note/name/ http://www.toly1994.com:8089/api/android/note/name/ materials / 2/2 - according to the type name query (see first type definition table) http://www.toly1994.com:8089/api/android/note/name/ABCS http://www.toly1994.com:8089/api/android/note/name/ABCS/2/2 - according to the id name check http://www.toly1994.com:8089/api/android/note/12 Add to delete interface -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- add - POST request: Update - PUT request: http://www.toly1994.com:8089/api/android/note http://www.toly1994.com:8089/api/android/note/1 DELETE - DELETE the request: http://www.toly1994.com:8089/api/android/note/1Copy the code

1. Get request

Note: Client can be any name you want, client accesses the server, so I use client

import 'package:http/http.dart' as client; main() { getData((data) { print(data); }); } getData(cbk) async { var api = 'http://www.toly1994.com:8089/api/android/note/100'; try { final response = await client.get(api); if (response.statusCode == 200) { cbk(response.body); } } catch (e) { print(e); }}Copy the code

If you think the callback is a bit low, you can also use Future.

main() { getData().then((data){ print(data); }); } Future<String> getData() async { try { final response = await client.get('http://www.toly1994.com:8089/api/android/note/100'); if (response.statusCode == 200) { return response.body; } } catch (e) { print(e); }}Copy the code

2. Post request: Insert data
main() { add((data) { print(data); }); } add(cbk) async { var api = 'http://www.toly1994.com:8089/api/android/note'; Var item = {"type": "C", "name": "insert ", "localPath": "null", "jianshuUrl": "https://www.jianshu.com/p/12f8ab32591a", "juejinUrl": "null", "imgUrl": "http://toly1994.com:8089/imgs/android/c3af376135a7abe0655c908195b271db.png", "createTime": "2018-09-06", "info": "null", "area": "A" }; try { final response = await client.post(api, body: item); if (response.statusCode == 200) { cbk(response.body); } } catch (e) { print(e); }}Copy the code


3. Put request: Update data
main() { set((data) { print(data); }); } set(cbk) async { var api = 'http://www.toly1994.com:8089/api/android/note/199'; Var item = {"type": "C", "name": "test ", "localPath": "null", "jianshuUrl": "https://www.jianshu.com/p/12f8ab32591a", "juejinUrl": "null", "imgUrl": "http://toly1994.com:8089/imgs/android/c3af376135a7abe0655c908195b271db.png", "createTime": "2018-09-06", "info": "null", "area": "A" }; try { final response = await client.put(api, body: item); if (response.statusCode == 200) { cbk(response.body); } } catch (e) { print(e); }}Copy the code


4. Delete request: Delete operation
main() { delete((data) { print(data); }); } delete(cbk) async { var api = 'http://www.toly1994.com:8089/api/android/note/199'; try { final response = await client.delete(api); if (response.statusCode == 200) { cbk(response.body); } } catch (e) { print(e); }}Copy the code


About Json

Generally parsing the JSON from the server side, non-back-end basically do not need to produce JSON

1. Convert json to objects
{"id": 100, "type": "draw related ", "name":" d5-android ", "localPath": "null", "jianshuUrl": "https://www.jianshu.com/p/12f8ab32591a", "juejinUrl": "null", "imgUrl": "http://toly1994.com:8089/imgs/android/c3af376135a7abe0655c908195b271db.png", "createTime": "2018-09-06", "info": "Previously in Html using JS control SVG or Canvas for motion simulation. Built-in browser window. RequestAnimationFrame can continuously perform rendering in this..." , "area": "A" }Copy the code
1.1: Create entity class, create constructor
class NoteBean {
  int id;
  String type;
  String name;
  String localPath;
  String jianshuUrl;
  String juejinUrl;
  String imgUrl;
  String createTime;
  String info;
  String area;

  NoteBean.fromJson(Map<String, dynamic> map)
      : id = map['id'],
        name = map['name'],
        localPath = map['localPath'],
        jianshuUrl = map['jianshuUrl'],
        juejinUrl = map['juejinUrl'],
        imgUrl = map['imgUrl'],
        createTime = map['createTime'],
        info = map['info'],
        area = map['area'];
}
Copy the code
var j = '{" id ": 100," type ":" drawing related ", "name" : "let the graphics of D5 - Android drawing up", "localPath" : "null", "jianshuUrl" : "https://www.jianshu.com/p/12f8ab3 2591a","juejinUrl":"null","imgUrl":"http://toly1994.com:8089/imgs/android/c3af376135a7abe0655c908195b271db.png","createT Use JS to control SVG or Canvas for motion simulation in Html. Built-in browser window. RequestAnimationFrame can continuously perform rendering in this..." ,"area":"A"}'; var noteBean = NoteBean.fromJson(json.decode(j)); print(noteBean.name); //D5-Android Drawing to make graphics moveCopy the code

2. Complex pair Json conversion (i.e. Json inside Json)
2.1: Json string to be processed
{" code ": 200," MSG ":" successful ", "data" : {" id ": 100," type ":" drawing related ", "name" : "let the graphics of D5 - Android drawing up", "localPath" : "null", "jianshuUrl": "https://www.jianshu.com/p/12f8ab32591a", "juejinUrl": "null", "imgUrl": "http://toly1994.com:8089/imgs/android/c3af376135a7abe0655c908195b271db.png", "createTime": "2018-09-06", "info": "Previously in Html using JS control SVG or Canvas for motion simulation. Built-in browser window. RequestAnimationFrame can continuously perform rendering in this..." , "area": "A" } }Copy the code

2.2: Adding an entity classResultBean
class ResultBean {
  String msg;
  int code;
  NoteBean data;

  ResultBean.fromJson(Map<String, dynamic> map)
      : msg = map['msg'],
        code = map['code'],
        data = NoteBean.fromJson(map['data']);
}
Copy the code

2.3: use:
var j = '{" code ": 200," MSG ":" successful ", "data" : {" id ": 100," type ":" drawing related ", "name" : "let the graphics of D5 - Android drawing up", "localPath" : "null", "jianshuUrl" : "h ttps://www.jianshu.com/p/12f8ab32591a","juejinUrl":"null","imgUrl":"http://toly1994.com:8089/imgs/android/c3af376135a7ab E0655c908195b271db. PNG ","createTime":"2018-09-06","info":" previously in Html using JS control SVG or Canvas motion simulation. Built-in browser window. RequestAnimationFrame can continuously perform rendering in this..." ,"area":"A"}}'; var result = ResultBean.fromJson(json.decode(j)); print(result.data.name); //D5-Android Drawing to make graphics moveCopy the code

3. Inline arrays for Json

In this case, data is an array of JSON, so the data processing of the accessing server interface is done

{" code ": 200," MSG ":" successful ", "data" : [{" id ": 198," type ":" drawing related ", "name" : ""," localPath ":" - ", "jianshuUrl" : "", "juejinUrl": "---", "imgUrl": "http://toly1994.com:8089/imgs/android/8a11d27d58f4c1fa4488cf39fdf68e76.png", "createTime": "2021-02-18", "info": "Hh" and "area", "A"}, {" id ": 200," type ":" drawing related ", "name" : ""," localPath ":" - ", "jianshuUrl" : ""," juejinUrl ": "---", "imgUrl": "http://toly1994.com:8089/imgs/android/8a11d27d58f4c1fa4488cf39fdf68e76.png", "createTime": "2018-12-21", "info": "hh", "area": "A" } ]Copy the code
class ResultBean {
  String msg;
  int code;
  var data;

  ResultBean.fromJson(Map<String, dynamic> map)
      : msg = map['msg'],
        code = map['code'],
        data = map['data'];
}

class NoteBean {
  int id;
  String type;
  String name;
  String localPath;
  String jianshuUrl;
  String juejinUrl;
  String imgUrl;
  String createTime;
  String info;
  String area;

  NoteBean.fromJson(Map<String, dynamic> map)
      : id = map['id'],
        name = map['name'],
        localPath = map['localPath'],
        jianshuUrl = map['jianshuUrl'],
        juejinUrl = map['juejinUrl'],
        imgUrl = map['imgUrl'],
        createTime = map['createTime'],
        info = map['info'],
        area = map['area'];
}
Copy the code
var j = '{" code ": 200," MSG ":" successful ", "data" : [{" id ": 198," type ":" drawing related ", "name" : ""," localPath ":" - ", "jianshuUrl" : ""," juejinUrl ":" -" ,"imgUrl":"http://toly1994.com:8089/imgs/android/8a11d27d58f4c1fa4488cf39fdf68e76.png","createTime":"2021-02-18","info": "Hh" and "area", "A"}, {" id ": 200," type ":" drawing related ", "name" : ""," localPath ":" - ", "jianshuUrl" : ""," juejinUrl ":" - ", "imgUrl" : "http:// toly1994.com:8089/imgs/android/8a11d27d58f4c1fa4488cf39fdf68e76.png","createTime":"2018-12-21","info":"hh","area":"A"}]} '; var result = ResultBean.fromJson(json.decode(j)); print(NoteBean.fromJson(result.data[1]).imgUrl); //http://toly1994.com:8089/imgs/android/8a11d27d58f4c1fa4488cf39fdf68e76.pngCopy the code

Well, that’s all for today, and tomorrow’s last day, please look forward to it


Postscript: Jie wen standard

1. Growth record and Errata of this paper
Program source code The date of note
V0.1 – making 2018-12-21 Day 6 — Asynchronous -IO+ Network + JSON
2. More about me
Pen name QQ WeChat hobby
Zhang Feng Jie te Li 1981462002 zdl1994328 language
My lot My Jane books I’m the nuggets Personal website
3. The statement

1—- This article is originally written by Zhang Fengjie, please note if reproduced

2—- welcome the majority of programming enthusiasts to communicate with each other 3—- personal ability is limited, if there is something wrong welcome to criticize and testify, must be humble to correct 4—- see here, I thank you here for your love and support