Add loader screen for --hot mode (#5113)
diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart index b8528c4..822f69d 100644 --- a/packages/flutter_tools/lib/src/asset.dart +++ b/packages/flutter_tools/lib/src/asset.dart
@@ -37,6 +37,7 @@ } bool get isStringEntry => _contents != null; + int get contentsLength => _contents.length; final File file; final String _contents;
diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart index de56314..c46fac9 100644 --- a/packages/flutter_tools/lib/src/devfs.dart +++ b/packages/flutter_tools/lib/src/devfs.dart
@@ -49,6 +49,17 @@ return _fileStat.modified.isAfter(_oldFileStat.modified); } + int get size { + if (_isSourceEntry) { + return bundleEntry.contentsLength; + } else { + if (_fileStat == null) { + _stat(); + } + return _fileStat.size; + } + } + void _stat() { if (_isSourceEntry) return; @@ -151,6 +162,8 @@ final Directory rootDirectory; final Map<String, DevFSEntry> _entries = <String, DevFSEntry>{}; final List<Future<Response>> _pendingWrites = new List<Future<Response>>(); + int _bytes = 0; + int get bytes => _bytes; Uri _baseUri; Uri get baseUri => _baseUri; @@ -166,6 +179,7 @@ } Future<dynamic> update([AssetBundle bundle = null]) async { + _bytes = 0; // Mark all entries as not seen. _entries.forEach((String path, DevFSEntry entry) { entry._wasSeen = false; @@ -244,6 +258,7 @@ entry._wasSeen = true; bool needsWrite = entry.isModified; if (needsWrite) { + _bytes += entry.size; Future<dynamic> pendingWrite = _operations.writeFile(fsName, entry); if (pendingWrite != null) { _pendingWrites.add(pendingWrite); @@ -261,11 +276,15 @@ _entries[devicePath] = entry; } entry._wasSeen = true; - Future<dynamic> pendingWrite = _operations.writeFile(fsName, entry); - if (pendingWrite != null) { - _pendingWrites.add(pendingWrite); - } else { - printTrace('DevFS: Failed to sync "$devicePath"'); + bool needsWrite = entry.isModified; + if (needsWrite) { + _bytes += entry.size; + Future<dynamic> pendingWrite = _operations.writeFile(fsName, entry); + if (pendingWrite != null) { + _pendingWrites.add(pendingWrite); + } else { + printTrace('DevFS: Failed to sync "$devicePath"'); + } } }
diff --git a/packages/flutter_tools/lib/src/run.dart b/packages/flutter_tools/lib/src/run.dart index d261c70..7eac9b7 100644 --- a/packages/flutter_tools/lib/src/run.dart +++ b/packages/flutter_tools/lib/src/run.dart
@@ -11,6 +11,7 @@ import 'base/logger.dart'; import 'base/utils.dart'; import 'build_info.dart'; +import 'cache.dart'; import 'commands/build_apk.dart'; import 'commands/install.dart'; import 'commands/trace.dart'; @@ -31,6 +32,15 @@ return targetPath; } +String getDevFSLoaderScript() { + return path.absolute(path.join(Cache.flutterRoot, + 'packages', + 'flutter', + 'bin', + 'loader', + 'loader_app.dart')); +} + class RunAndStayResident { RunAndStayResident( this.device, { @@ -176,7 +186,9 @@ if (traceStartup != null) platformArgs = <String, dynamic>{ 'trace-startup': traceStartup }; - printStatus('Running ${getDisplayPath(_mainPath)} on ${device.name}...'); + if (!hotMode || (hotMode && !device.needsDevFS)) + printStatus('Running ${getDisplayPath(_mainPath)} on ${device.name}...'); + _loggingSubscription = device.logReader.logLines.listen((String line) { if (!line.contains('Observatory listening on http') && !line.contains('Diagnostic server listening on http')) @@ -186,7 +198,7 @@ _result = await device.startApp( _package, debuggingOptions.buildMode, - mainPath: _mainPath, + mainPath: (hotMode && device.needsDevFS) ? getDevFSLoaderScript() : _mainPath, debuggingOptions: debuggingOptions, platformArgs: platformArgs, route: route @@ -213,7 +225,7 @@ printError('Could not perform initial file synchronization.'); return 3; } - printStatus('Launching from sources.'); + printStatus('Running ${getDisplayPath(_mainPath)} on ${device.name}...'); await _launchFromDevFS(_package, _mainPath); } observatory.populateIsolateInfo(); @@ -345,9 +357,10 @@ }); } - Status devFSStatus = logger.startProgress('Updating files on device...'); + Status devFSStatus = logger.startProgress('Syncing files on device...'); await _devFS.update(); devFSStatus.stop(showElapsedTime: true); + printStatus('Synced ${getSizeAsMB(_devFS.bytes)} MB'); return true; } @@ -388,7 +401,13 @@ reloadStatus.stop(showElapsedTime: true); Status reassembleStatus = logger.startProgress('Reassembling application'); - await observatory.flutterReassemble(observatory.firstIsolateId); + try { + await observatory.flutterReassemble(observatory.firstIsolateId); + } catch (_) { + reassembleStatus.stop(showElapsedTime: true); + printError('Reassembling application failed.'); + return false; + } reassembleStatus.stop(showElapsedTime: true); return true; }