Commit b11b2a1d authored by John McCutchan's avatar John McCutchan Committed by GitHub

Add loader screen for --hot mode (#5113)

parent 578d98ea
This directory contains a small Flutter application that is run while
an application is being copied onto the device.
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: 'Flutter Initial Load',
home: new Scaffold(
body: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text('Loading application onto device...',
style: new TextStyle(fontSize: 24.0)),
new CircularProgressIndicator(value: null)
]
)
)
)
);
}
......@@ -37,6 +37,7 @@ class AssetBundleEntry {
}
bool get isStringEntry => _contents != null;
int get contentsLength => _contents.length;
final File file;
final String _contents;
......
......@@ -49,6 +49,17 @@ class DevFSEntry {
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 @@ class DevFS {
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 @@ class DevFS {
}
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 @@ class DevFS {
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 @@ class DevFS {
_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"');
}
}
}
......
......@@ -11,6 +11,7 @@ import 'application_package.dart';
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 @@ String findMainDartFile([String target]) {
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 @@ class RunAndStayResident {
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 @@ class RunAndStayResident {
_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 @@ class RunAndStayResident {
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 @@ class RunAndStayResident {
});
}
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 @@ class RunAndStayResident {
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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment