Flutter搭建环境的下载Gradle Wrapper的问题的一个解决方式

来源:互联网 发布:网络监听工具 编辑:程序博客网 时间:2024/06/16 11:47

Flutter搭建环境的下载Gradle Wrapper的问题的一个解决方式

按照https://flutter.io/或者https://codelabs.developers.google.com/codelabs/flutter/#1的步骤搭建环境:

flutter doctor: 编译源码,下载依赖

Building flutter tool...Downloading Material fonts...                         0.7sDownloading package sky_engine...                     0.6sDownloading common tools...                           1.0sDownloading darwin-x64 tools...                       8.3sDownloading darwin-x64 tools...                       8.9sDownloading android-arm-profile/darwin-x64 tools...   1.8sDownloading android-arm-release/darwin-x64 tools...   1.0sDownloading android-x86 tools...                      4.1sDownloading android-x64 tools...                      4.2sDownloading android-arm tools...                      2.1sDownloading android-arm-profile tools...              1.6sDownloading android-arm-release tools...              1.7sDownloading ios tools...                              6.9sDownloading ios-profile tools...                      5.4sDownloading ios-release tools...                      7.4sDownloading Gradle Wrapper...

结果在bin/cache目录下生成了:

artifactsdart-sdkdart-sdk.stampengine.stampflutter_tools.snapshotflutter_tools.stamplockfilematerial_fonts.stamppkg

这一步卡住了:Downloading Gradle Wrapper…

SocketException: SocketException: Connection failed (OS Error: No route to host, errno = 65), address = android.googlesource.com, port = 443

或者其他错误,总之原因就是连接不上android.googlesource.com(但是浏览器却可以打开)

于是查到这些文章:

https://github.com/getlantern/forum/issues/29
https://github.com/getlantern/lantern/issues/3341
http://www.jianshu.com/p/411a60f415a5

无论是设置(Lantern):

export http_proxy=127.0.0.1:61537export https_proxy=127.0.0.1:61538

还是设置(Shadowsocks):

export http_proxy=socks5://127.0.0.1:1080export https_proxy=$http_proxy

结果是:

curl https://android.googlesource.com/

没有问题,但是

curl https://www.google.com/

出错:Server aborted the SSL handshake。并且flutter doctor依旧出错(仍然是https://android.googlesource.com/无法访问;但是https://storage.googleapis.com/flutter_infra/flutter/$version/却可以访问)。

于是查看log:

SocketException: SocketException: Connection failed (OS Error: No route to host, errno = 65), address = android.googlesource.com, port = 443 10 11 ``` 12 #0      fetchUrl (package:flutter_tools/src/base/net.dart:18) 13 <asynchronous suspension> 14 #1      _downloadFile (package:flutter_tools/src/cache.dart:408) 15 <asynchronous suspension> 16 #2      _downloadZippedTarball.<anonymous closure> (package:flutter_tools/src/cache.dart:424) 17 <asynchronous suspension> 18 #3      _withTemporaryFile (package:flutter_tools/src/cache.dart:436) 19 <asynchronous suspension> 20 #4      _downloadZippedTarball (package:flutter_tools/src/cache.dart:423) 21 #5      GradleWrapper.updateInner (package:flutter_tools/src/cache.dart:397) 22 <asynchronous suspension> 23 #6      CachedArtifact.update (package:flutter_tools/src/cache.dart:223) 24 <asynchronous suspension> 25 #7      Cache.updateAll (package:flutter_tools/src/cache.dart:196) 26 <asynchronous suspension> 27 #8      FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:225) 28 <asynchronous suspension> 29 #9      FlutterCommand.run (package:flutter_tools/src/runner/flutter_command.dart:181) 30 <asynchronous suspension> 31 #10     CommandRunner.runCommand (package:args/command_runner.dart:194) 32 <asynchronous suspension> 33 #11     FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:276) 34 <asynchronous suspension> 35 #12     CommandRunner.run.<anonymous closure> (package:args/command_runner.dart:109) 36 #13     new Future.sync (dart:async/future.dart:222) 37 #14     CommandRunner.run (package:args/command_runner.dart:109) 38 #15     FlutterCommandRunner.run (package:flutter_tools/src/runner/flutter_command_runner.dart:161) 39 #16     run.<anonymous closure> (package:flutter_tools/executable.dart:143) 40 <asynchronous suspension> 41 #17     AppContext._run (package:flutter_tools/src/base/context.dart:76) 42 <asynchronous suspension> 43 #18     AppContext.runInZone.<anonymous closure> (package:flutter_tools/src/base/context.dart:66) 44 #19     _rootRun (dart:async/zone.dart:1120) 45 #20     _CustomZone.run (dart:async/zone.dart:1001) 46 #21     runZoned (dart:async/zone.dart:1467) 47 #22     AppContext.runInZone (package:flutter_tools/src/base/context.dart:65) 48 #23     run (package:flutter_tools/executable.dart:114)

于是打开源文件修改:packages/flutter_tools/lib/src/cache.dart:

   bool isUpToDate() {    ////////////////////////////////////////这些log是我加上的////////////////////////////////////////    var stamp = cache.getStampFor(name);    // logger.writeToStdOut    logger.writeToStdOut('\n==============isUpToDate? location, version, getStampFor: ');    logger.writeToStdOut('\nname: ');    logger.writeToStdOut( name );    logger.writeToStdOut('\nlocation: ');    logger.writeToStdOut( location.path );    logger.writeToStdOut('\nversion: ');    logger.writeToStdOut( version );    logger.writeToStdOut('\nstamp: ');    logger.writeToStdOut( stamp);    logger.writeToStdOut('\n');    ////////////////////////////////////////////这些log是我加上的////////////////////////////////////     if (!location.existsSync()) {        // 目标文件夹是否存在,不存在去下载       logger.writeToStdOut('\nlocation not exists');       return false;     }     if (version != cache.getStampFor(name)) {        // 目标文件夹存在,检查version的stamp(理解为版本号)是否与version相同,不同就去下载       logger.writeToStdOut('\nStamp not match');       return false;     }     // 默认一直下载     return isUpToDateInner();   }   /// Download a file from the given [url] and write it to [location].   Future<Null> _downloadFile(Uri url, File location) async {     _ensureExists(location.parent);     ////////////////////////////////////////////这些log是我加上的////////////////////////////////////     logger.writeToStdOut('\n_downloadFile path : ' + location.path);     ////////////////////////////////////////////这些log是我加上的////////////////////////////////////     final List<int> fileBytes = await fetchUrl(url);     location.writeAsBytesSync(fileBytes, flush: true);   }   /// Download a zip archive from the given [url] and unzip it to [location].   Future<Null> _downloadZipArchive(Uri url, Directory location) {       ////////////////////////////////////////////这些log是我加上的////////////////////////////////////    logger.writeToStdOut('\n_downloadZip : ' + location.path);        ////////////////////////////////////////////这些log是我加上的////////////////////////////////////     return _withTemporaryFile('download.zip', (File tempFile) async {       await _downloadFile(url, tempFile);       _ensureExists(location);       os.unzip(tempFile, location);     });   }   /// Download a gzipped tarball from the given [url] and unpack it to [location].   Future<Null> _downloadZippedTarball(Uri url, Directory location) {       ////////////////////////////////////////////这些log是我加上的////////////////////////////////////    logger.writeToStdOut('\n_downloadZipped:' + location.path);        ////////////////////////////////////////////这些log是我加上的////////////////////////////////////   return _withTemporaryFile('download.tgz', (File tempFile) async {       await _downloadFile(url, tempFile);       _ensureExists(location);       os.unpack(tempFile, location);     });   }

做了些修改,发现里面的逻辑很简单:

  Future<Null> updateAll() async {    if (!_lockEnabled)      return null;    for (CachedArtifact artifact in _artifacts) {      if (!artifact.isUpToDate())      // 如果需要更新,那么更新        await artifact.update();    }  }

artifact.update里面的逻辑就是检查文件是否存在、版本是否一致,满足条件,就不用更新,否则下载。下载的逻辑就是先下载到一个临时目录,然后解压到bin/cache,并且创建一个xxx.stamp文件记录版本号。

然后删除bin/cache目录下的flutter_tools.stamp和flutter_tools.snapshot,再次执行flutter doctor:

==============isUpToDate? location, version, getStampFor:name: material_fontslocation: /Users/wangshenglong/flutter/bin/cache/artifacts/material_fontsversion: https://storage.googleapis.com/flutter_infra/flutter/fonts/13ac995daa9dda0a6ba0a45f1fccc541e616a74c/fonts.zipstamp: https://storage.googleapis.com/flutter_infra/flutter/fonts/13ac995daa9dda0a6ba0a45f1fccc541e616a74c/fonts.zip==============isUpToDate? location, version, getStampFor:name: enginelocation: /Users/wangshenglong/flutter/bin/cache/artifacts/engineversion: 31d03de019794a4b0e3c98c04cf7be501fb962fbstamp: 31d03de019794a4b0e3c98c04cf7be501fb962fb==============isUpToDate? location, version, getStampFor:name: gradle_wrapperlocation: /Users/wangshenglong/flutter/bin/cache/artifacts/gradle_wrapperversion: 0b5c1398d1d04ac245a310de98825cb7b3278e2astamp: nullDownloading Gradle Wrapper...https://android.googlesource.com/platform/tools/base/+archive/0b5c1398d1d04ac245a310de98825cb7b3278e2a/templates/gradle/wrapper.tgz     -_downloadZipped:/Users/wangshenglong/flutter/bin/cache/artifacts/gradle_wrapper_downloadFile path : /var/folders/qx/yr3zc94x2sbf16ptpv5v5_tr0000gn/T/7XQy4z/download.tgz

所以,解决问题就简单了:

1.浏览器下载https://android.googlesource.com/platform/tools/base/+archive/0b5c1398d1d04ac245a310de98825cb7b3278e2a/templates/gradle/wrapper.tgz,解压到flutter/bin/cache/artifacts/gradle_wrapper目录下;2.在flutter/bin/cache/下创建gradle_wrapper.stamp文件,写入内容0b5c1398d1d04ac245a310de98825cb7b3278e2a。完成。

再次运行flutter doctor:

==============isUpToDate? location, version, getStampFor:name: material_fontslocation: /Users/wangshenglong/flutter/bin/cache/artifacts/material_fontsversion: https://storage.googleapis.com/flutter_infra/flutter/fonts/13ac995daa9dda0a6ba0a45f1fccc541e616a74c/fonts.zipstamp: https://storage.googleapis.com/flutter_infra/flutter/fonts/13ac995daa9dda0a6ba0a45f1fccc541e616a74c/fonts.zip==============isUpToDate? location, version, getStampFor:name: enginelocation: /Users/wangshenglong/flutter/bin/cache/artifacts/engineversion: 31d03de019794a4b0e3c98c04cf7be501fb962fbstamp: 31d03de019794a4b0e3c98c04cf7be501fb962fb==============isUpToDate? location, version, getStampFor:name: gradle_wrapperlocation: /Users/wangshenglong/flutter/bin/cache/artifacts/gradle_wrapperversion: 0b5c1398d1d04ac245a310de98825cb7b3278e2astamp: 0b5c1398d1d04ac245a310de98825cb7b3278e2a[✓] Flutter (on Mac OS X 10.11.2 15C50, locale zh-Hans, channel alpha)    • Flutter at /Users/wangshenglong/flutter    • Framework revision 701d534ba9 (7 days ago), 2017-09-12 14:01:51 -0700    • Engine revision 31d03de019    • Tools Dart version 1.25.0-dev.11.0[✓] Android toolchain - develop for Android devices (Android SDK 25.0.3)    • Android SDK at /Users/wangshenglong/Documents/DevSoftware/Android_Studio    • Platform android-25, build-tools 25.0.3    • ANDROID_HOME = /Users/wangshenglong/Documents/DevSoftware/Android_Studio    • Java binary at: /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java    • Java version Java(TM) SE Runtime Environment (build 1.7.0_79-b15)[-] iOS toolchain - develop for iOS devices (Xcode 7.3)    • Xcode at /Applications/Xcode.app/Contents/Developer    • Xcode 7.3, Build version 7D175    ✗ Flutter requires a minimum Xcode version of 8.0.0.      Download the latest version or update via the Mac App Store.    ✗ libimobiledevice and ideviceinstaller are not installed or require updating. To update, run:        brew uninstall --ignore-dependencies libimobiledevice        brew install --HEAD libimobiledevice        brew install ideviceinstaller    ✗ ios-deploy not installed. To install:        brew install ios-deploy    ✗ CocoaPods not installed.        CocoaPods is used to retrieve the iOS platform side's plugin code that responds to your plugin usage on the Dart side.        Without resolving iOS dependencies with CocoaPods, plugins will not work on iOS.        For more info, see https://flutter.io/platform-plugins      To install:        brew install cocoapods        pod setup[✗] Android Studio (not installed)    • Android Studio not found; download from https://developer.android.com/studio/index.html      (or visit https://flutter.io/setup/#android-setup for detailed instructions).[✓] IntelliJ IDEA Ultimate Edition (version 2017.2.4)    • Flutter plugin version 17.0    • Dart plugin version 172.4155.35[✓] Connected devices    • Samsung Galaxy S6, 6 0 0, API 23, 1440x2560 • 192.168.62.101:5555 • android-x86 • Android 6.0 (API 23)

大功告成。

附录:

1.logger的用法我也不知道,但是packages/flutter_tools/lib/src/base/logger.dart有源文件,于是就知道了用法:printError,printStatus,writeToStdOut,printTrace,startProgress。

2.File.path我也不知道,于是google,找到https://www.dartlang.org/dart-vm/dart-by-example,查下api就知道了。

阅读全文
0 0