Musa Usman
Musa Usman

Reputation: 711

How to wait for code to be executed before executing next code in Dart?

I am working on a wallpaper app in Flutter & Dart. Currently I'm working on the set wallpaper button where I need to check if the wallpaper file exists, download it if need to and then change the wallpaper.

This is what I have right now and I think I've done it right, please note that I'm and Android Java Developer with only about 6 months of experience so I am beyond the basics in Dart too but not too good.

DOWNLOAD WALLPAPER FUNCTION

static Future<int> downloadWallpaperFile(int wallpaperID,
  {String path}) async {
///Prepare a url for downloading the wallpaper using the getWallpaperURL method and passing in fullSizedWallpaper string constant
String url = getWallpaperURL(WallpaperSize.fullWallpaper, wallpaperID);

///Log output
print('CallingDownloadWallpaper : ' + url);

///Visual Feedback
wallpaperDetailsPageScaffoldGlobalKey.currentState.showSnackBar(
    new SnackBar(content: new Text('Starting Wallpaper Download...')));

///Start downloading the wallpaper file from the url
var data = http.readBytes(url);

///After download is completed
data.then((buffer) async {
  ///If filePath is not passed in as parameter
  if (path == null) {
    ///Use getPathForWallpaperFile to get a path for a wallpaper file
    path = await getPathForWallpaperFile(url);
  }

  ///Create a new file at the path, the path also includes the name of the file which is the id of the wallpaper
  File newFile = new File(path);

  ///Get write access to the newly created wallpaper file
  RandomAccessFile rf = newFile.openSync(mode: FileMode.write);

  ///Write the downloaded data to the file synchronously
  rf.writeFromSync(buffer);

  ///Save the file to the disk synchronously
  rf.flushSync();

  ///Close access to file synchronously
  rf.closeSync();

  ///Log output
  print('DownloadWallpaperResult : Complete');

  ///Visual Feedback
  wallpaperDetailsPageScaffoldGlobalKey.currentState.showSnackBar(
      new SnackBar(content: new Text('Wallpaper Download Complete')));
});
return 0;
}

SET WALLPAPER FUNCTION

static setWallpaper(int wallpaperID) async {
///Prepare variables for setting wallpaper and download the wallpaper as well (if needed)
String url = getWallpaperURL(WallpaperSize.fullWallpaper, wallpaperID);
String path = await getPathForWallpaperFile(url);
bool fileExists = checkIfFileExists(path);

///If wallpaper file does not exist then download it
if (fileExists == false) {
  ///Download wallpaper then change wallpaper
  await downloadWallpaperFile(wallpaperID, path: path).then((result) {
    ///Check if download was successful
    if (result == 0) {
      ///Change wallpaper
      AndroidInterface.setWallpaper(path);
    }
  });
} else {
  ///Wallpaper already downloaded
  ///Change wallpaper
  AndroidInterface.setWallpaper(path);
}
}

Upvotes: 2

Views: 2134

Answers (1)

boformer
boformer

Reputation: 30103

The problem is that you are using then, which is non-blocking (basically the old way to use Futures without await).

Instead, use await:

static Future<int> downloadWallpaperFile(int wallpaperID, {String path}) async {
  // ...

  //Start downloading the wallpaper file from the url
  final buffer = await http.readBytes(url);

  //After download is completed

  //If filePath is not passed in as parameter
  if (path == null) {
    //Use getPathForWallpaperFile to get a path for a wallpaper file
    path = await getPathForWallpaperFile(url);
  }

  // ...

  return 0;
}

Btw, /// is reserved for documentation on classes and fields, use // for in-method comments!

I'm also not sure if it is a good idea to use synchronous io actions. That will probably block the UI of the app, it would be better to use the async io api (again with await).

Upvotes: 4

Related Questions