简体   繁体   English

在Flutter项目上创建Android库

[英]Create Android Library on Flutter project

I am trying to create an android library on top of flutter project for distribution. 我正在尝试在flutter项目之上创建一个android库以进行分发。 I have developed an app using flutter, but I want to wrap it in an Android library. 我使用flutter开发了一个应用程序,但我想将其包装在Android库中。 I keep getting error Transform output file /Users/Dev/Documents/projects/LibExample/testlib/build/intermediates/flutter/flutter-x86.jar does not exist. 我不断收到错误Transform output file /Users/Dev/Documents/projects/LibExample/testlib/build/intermediates/flutter/flutter-x86.jar does not exist. I have read search almost everything online, but nothing so far. 我已经阅读了几乎所有在线搜索内容,但到目前为止没有任何内容。

The LibExample is my sample app to use the library while testlib is the Android library. LibExample是我的示例应用程序,使用库,而testlib是Android库。 In the testlib I have set up my build.graddle to locate the flutter.sdk . testlib我设置了build.graddle来定位flutter.sdk I have also specified the flutter source location. 我还指定了颤振源的位置。 Each time I sync the gradle file, I get the error /Users/Dev/Documents/projects/LibExample/testlib/build/intermediates/flutter/flutter-x86.jar does not exist. 每次我sync gradle文件时,都会收到错误/Users/Dev/Documents/projects/LibExample/testlib/build/intermediates/flutter/flutter-x86.jar不存在。 ` `

Here is the output for flutter doctor -v . 这是flutter doctor -v的输出。

flutter doctor -v
[✓] Flutter (Channel beta, v0.5.2-pre.1, on Mac OS X 10.13.6 17G65, locale en-US)
    • Flutter version 0.5.2-pre.1 at /Users/Dev/Downloads/flutter
    • Framework revision 142e2f41ba (9 weeks ago), 2018-09-03 12:50:53 +0100
    • Engine revision 1ed25ca7b7
    • Dart version 2.0.0-dev.58.0.flutter-f981f09760

[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
    • Android SDK at /Users/Dev/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
    • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.1, Build version 10B61
    • ios-deploy 1.9.2
    • CocoaPods version 1.5.3

[✓] Android Studio (version 3.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 29.1.1
    • Dart plugin version 181.5656
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)

[!] VS Code (version 1.28.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension not installed; install from
      https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected devices (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 5.1.1 (API 22) (emulator)

! Doctor found issues in 1 category.

I finally stumble on this feature on one of flutter wiki page . 我最终在一个颤抖的Wiki 页面上偶然发现了此功能。 A very important thing to note as of this write-up; 撰写本文时要注意的一件非常重要的事情;

The "add2app" support is in preview, and is so far only available on the master channel. “ add2app”支持处于预览状态,到目前为止仅在主频道上可用。

Although this feature is still experimental but it works fine (few snags tho, like the time it takes to launch the flutter app when you call in from the Android host). 尽管此功能仍处于试验阶段,但可以正常工作(很少遇到这种情况,例如从Android主机调用时启动flutter应用程序所需的时间)。

Flutter projects created using flutter create xxx include very simple host apps for your Flutter/Dart code (a single-Activity Android host and a single-ViewController iOS host). 使用flutter create xxx创建的Flutter项目包括用于Flutter / Dart代码的非常简单的宿主应用程序(单个Activity Android宿主和单个ViewController iOS宿主)。 You can modify these host apps to suit your needs and build from there. 您可以修改这些主机应用程序以适合您的需求并从那里构建。

But if you're starting off with an existing host app for either platform, you'll likely want to include your Flutter project in that app as some form of library instead. 但是,如果您要从任一平台的现有主机应用程序开始,则可能需要将Flutter项目作为某种形式的库包含在该应用程序中。

This is what the Flutter module template provides. 这就是Flutter模块模板所提供的。 Executing flutter create -t module xxx produces a Flutter project containing an Android library and a Cocoapods pod designed for consumption by your existing host app. 执行flutter create -t module xxx会生成一个Flutter项目,其中包含一个Android库和一个Cocoapods Pod,供您的现有主机应用程序使用。

Android 安卓系统

Create a Flutter module Let's assume you have an existing Android app at some/path/MyApp, and that you want your Flutter project as a sibling: 创建Flutter模块假设您在some / path / MyApp上已有一个Android应用,并且希望Flutter项目作为同级项目:

$ cd some/path/
$ flutter create -t module my_flutter

This creates a some/path/my_flutter/ Flutter module project with some Dart code to get you started and a .android/ hidden subfolder that wraps up the module project in an Android library. 这将创建一个some/path/my_flutter/ Flutter模块项目,其中包含一些Dart代码以帮助您入门,以及一个.android/隐藏子文件夹,该子文件夹将模块项目包装在Android库中。

(While not required in what follows, if you so desire, you can build that library using Gradle: (尽管随后不需要,但如果您愿意,可以使用Gradle构建该库:

$ cd .android/
$ ./gradlew flutter:assembleDebug

This results in a flutter-debug.aar archive file in .android/Flutter/build/outputs/aar/. 这将在.android/Flutter/build/outputs/aar/.中生成flutter-debug.aar存档文件.android/Flutter/build/outputs/aar/.

Make the host app depend on the Flutter module 使主机应用程序依赖Flutter模块

Include the Flutter module as a sub-project in the host app's settings.gradle : 将Flutter模块作为子项目包含在主机应用程序的settings.gradle

// MyApp/settings.gradle
include ':app'                                     // assumed existing content
setBinding(new Binding([gradle: this]))                                 // new
evaluate(new File(                                                      // new
  settingsDir.parentFile,                                               // new
  'my_flutter/.android/include_flutter.groovy'                          // new
))                                                                      // new

The binding and script evaluation allows the Flutter module to include itself (as :flutter ) and any Flutter plugins used by the module (as :package_info , :video_player , etc) in the evaluation context of your settings.gradle . 绑定和脚本评估允许扑模块include本身(如:flutter )和模块(如使用任何插件扑:package_info:video_player等)在你的评价方面settings.gradle

Introduce an implementation dependency on the Flutter module from your app: 在您的应用中引入对Flutter模块的implementation依赖性:

// MyApp/app/build.gradle
:
dependencies {
  implementation project(':flutter')
  :
}

Use the Flutter module from your Java code 使用Java代码中的Flutter模块

Use the Flutter module's Java API to add Flutter views to your host app. 使用Flutter模块的Java API将Flutter视图添加到您的主机应用程序。 This can be done by directly using Flutter.createView : 这可以通过直接使用Flutter.createView来完成:

// MyApp/app/src/main/java/some/package/MainActivity.java
fab.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    View flutterView = Flutter.createView(
      MainActivity.this,
      getLifecycle(),
      "route1"
    );
    FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600, 800);
    layout.leftMargin = 100;
    layout.topMargin = 200;
    addContentView(flutterView, layout);
  }
});

It is also possible to create a FlutterFragment that takes care of lifecycle by itself: 也可以创建一个FlutterFragmentFlutterFragment处理生命周期:

// MyApp/app/src/main/java/some/package/SomeActivity.java
fab.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
    tx.replace(R.id.someContainer, Flutter.createFragment("route1"));
    tx.commit();
  }
});

Above we use the string "route1" to tell the Dart code which widget to display in the Flutter view. 在上方,我们使用字符串"route1"告诉Dart代码在Flutter视图中显示哪个小部件。 The lib/main.dart file of the Flutter module project template should switch on (or otherwise interpret) the provided route string, available as window.defaultRouteName , to determine which widget to create and pass to runApp . Flutter模块项目模板的lib/main.dart文件应switch (或解释)所提供的路由字符串(可作为window.defaultRouteName ,以确定要创建哪个窗口小部件并将其传递给runApp Schematically, 示意地,

import 'dart:ui';
import 'package:flutter/material.dart';

void main() => runApp(_widgetForRoute(window.defaultRouteName));

Widget _widgetForRoute(String route) {
  switch (route) {
    case 'route1':
      return SomeWidget(...);
    case 'route2':
      return SomeOtherWidget(...);
    default:
      return Center(
        child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
      );
  }
}

It is entirely up to you which route strings you want and how to interpret them. 路由字符串以及如何解释字符串完全取决于您。

Building and running your app 生成并运行您的应用

You build and run MyApp in exactly the same way that you did before you added the Flutter module dependency, typically using Android Studio. 您以与添加Flutter模块依赖项之前(通常使用Android Studio)完全相同的方式构建和运行MyApp The same goes for editing, debugging, and profiling your Android code. 编辑,调试和分析Android代码也是如此。

Hot restart/reload and debugging Dart code 热重启/重新加载和调试Dart代码

Full IDE integration to support working with the Flutter/Dart code of your hybrid app is work in progress. 正在进行全面的IDE集成以支持与混合应用程序的Flutter / Dart代码一起使用。 But the fundamentals are already present via the Flutter command line tools and the Dart Observatory web user interface. 但是基本原理已经通过Flutter命令行工具和Dart Observatory Web用户界面提供。

Connect a device or launch an emulator. 连接设备或启动仿真器。 Then make Flutter CLI tooling listen for your app to come up: 然后使Flutter CLI工具监听您的应用程序:

$ cd some/path/my_flutter
$ flutter attach

Waiting for a connection from Flutter on Nexus 5X... Launch MyApp in debug mode from Android Studio (or whichever way you usually do it). 正在等待Nexus 5X上Flutter的连接...从Android Studio中以调试模式启动MyApp (或通常采用的任何一种方式)。 Navigate to an area of the app that uses Flutter. 导航到使用Flutter的应用程序区域。 Then turn back to the terminal, and you should see output similar to the following: 然后回到终端,您应该看到类似于以下内容的输出:

Done.
Syncing files to device Nexus 5X...                          5.1s

🔥  To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
An Observatory debugger and profiler on Nexus 5X is available at: http://127.0.0.1:59556/
For a more detailed help message, press "h". To quit, press "q".

You can now edit the Dart code in my_flutter , and the changes can be hot reloaded by pressing r in the terminal. 现在,您可以在my_flutter编辑Dart代码,然后可以通过在终端中按r来重新加载更改。 You can also paste the URL above into your browser to use the Dart Observatory for setting breakpoints, analyzing memory retention and other debugging tasks. 您也可以将上面的URL粘贴到浏览器中,以使用Dart Observatory设置断点,分析内存保留和其他调试任务。

iOS Create a Flutter module iOS 创建Flutter模块

Let's assume you have an existing iOS app at some/path/MyApp , and that you want your Flutter project as a sibling: 假设您在some/path/MyApp有一个现有的iOS应用程序,并且您希望Flutter项目作为同级项目:

$ cd some/path/
$ flutter create -t module my_flutter

This creates a some/path/my_flutter/ Flutter module project with some Dart code to get you started and a .ios/ hidden subfolder that wraps up the module project that contains some Cocoapods and a helper Ruby script. 这将创建一个some/path/my_flutter/ Flutter模块项目,其中包含一些Dart代码以帮助您入门;以及一个.ios/隐藏子文件夹,该子文件夹包装了包含一些Cocoapods和一个辅助Ruby脚本的模块项目。

Make the host app depend on the Flutter module 使主机应用程序依赖Flutter模块

The description below assumes that your existing iOS app has a structure similar to what you get by asking Xcode version 10.0 to generate a new "Single View App" project using Objective-C. 下面的描述假定您现有的iOS应用程序具有与要求Xcode版本10.0使用Objective-C生成新的“单视图应用程序”项目所得到的结构类似的结构。 If your existing app has a different folder structure and/or existing .xcconfig files, you can reuse those, but probably need to adjust some of the relative paths mentioned below accordingly. 如果您现有的应用程序具有不同的文件夹结构和/或现有的.xcconfig文件,则可以重用它们,但可能需要相应地调整下面提到的一些相对路径。

The assumed folder structure is as follows: 假定的文件夹结构如下:

some/path/
  my_flutter/
    lib/main.dart
    .ios/
  MyApp/
    MyApp/
      AppDelegate.h
      AppDelegate.m (or swift)
      :

Add your Flutter app to your Podfile 将Flutter应用添加到Podfile

Integrating the Flutter framework requires use of the CocoaPods dependency manager. 集成Flutter框架需要使用CocoaPods依赖关系管理器。 This is because the Flutter framework needs to be available also to any Flutter plugins that you might include in my_flutter. 这是因为Flutter框架也需要对my_flutter中可能包含的所有Flutter插件可用。

Please refer to cocoapods.org for how to install CocoaPods on your development machine, if needed. 如果需要,请访问cocoapods.org ,了解如何在您的开发计算机上安装CocoaPods。

If your host application ( MyApp ) is already using Cocoapods, you only have to do the following to integrate with your my_flutter app: 如果您的宿主应用程序( MyApp )已在使用Cocoapods,则只需执行以下操作即可与my_flutter应用程序集成:

Add the following lines to your Podfile : Podfile添加到您的Podfile

flutter_application_path = 'path/to/flutter_app/'
  eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)

Run pod install . 运行pod install

Whenever you change the Flutter plugin dependencies in some/path/my_flutter/pubspec.yaml , you need to run flutter packages get from some/path/my_flutter to refresh the list of plugins read by the podhelper.rb script. 每当您更改some/path/my_flutter/pubspec.yaml的Flutter插件依赖关系时,都需要运行从some/path/my_flutter获取的flutter软件包,以刷新podhelper.rb脚本读取的插件列表。 Then run pod install again from some/path/MyApp . 然后从some/path/MyApp再次运行pod install。

The podhelper.rb script will ensure that your plugins and the Flutter.framework get added to your project, and also ensure that bitcode is disabled for all targets. podhelper.rb脚本将确保将插件和Flutter.framework添加到项目中,并确保所有目标均禁用了位码。

Add a build phase for building the Dart code 添加用于构建Dart代码的构建阶段

Select the top-level MyApp project in the Project navigator. 在“项目”导航器中选择顶级MyApp项目。 Select TARGET MyApp in the left part of the main view, and then select the Build Phases tab. 在主视图的左侧选择TARGET MyApp ,然后选择Build Phases选项卡。 Add a new build phase by clicking the + towards the top left of the main view. 通过单击主视图左上角的+添加一个新的构建阶段。 Select New Run Script Phase. 选择“ New Run Script阶段”。 Expand the new Run Script , just appended to the list of phases. 展开新的Run Script ,将其添加到阶段列表中。

Paste the following into the text area just below the Shell field: 将以下内容粘贴到“外壳”字段下方的文本区域中:

"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed

Finally, drag the new build phase to just after the Target Dependencies phase. 最后,将新的构建阶段拖到“目标依赖项”阶段之后。

You should now be able to build the project using ⌘B . 现在,您应该可以使用⌘B来构建项目。

Under the hood If you have some reason to do this manually or debug why these steps aren't working, here's what's going on under the hood: 如果您出于某些原因手动执行此操作或调试为什么这些步骤不起作用,请执行以下操作:

  1. Flutter.framework (the Engine library) is getting embedded into your app for you. Flutter.framework (引擎库)已为您嵌入到您的应用程序中。 This has to match up with the release type (debug/profile/release) as well as the architecture for your app (arm*, i386, x86_64, etc.). 这必须与发行版类型(调试/配置文件/发行版)以及应用程序的架构(arm *,i386,x86_64等)相匹配。 Cocoapods pulls this in as a vendored framework and makes sure it gets embedded into your native app. Cocoapods将其作为供应商框架引入,并确保将其嵌入到您的本机应用程序中。
  2. App.framework (your Flutter application binary) is embedded into your app. App.framework (您的Flutter应用程序二进制文件)已嵌入到您的应用程序中。
  3. flutter_assets folder is getting embedded as a resource - it contains fonts, images, and in certain build modes it also contains binary files required by the engine at runtime. flutter_assets文件夹作为资源被嵌入-它包含字体,图像,并且在某些构建模式下,它还包含引擎在运行时所需的二进制文件。 Problems with this folder can lead to runtime errors such as "Could not run engine for configuration" - usually indicating that either the folder is not getting embedded, or you're trying to cross a JIT application with an AOT enabled engine, or vice versa! 此文件夹的问题可能会导致运行时错误,例如“无法运行引擎以进行配置”-通常表明该文件夹未嵌入,或者您正试图将JIT应用程序与启用了AOT的引擎进行交互,反之亦然!
  4. Any plugins are getting added as Cocoapods. 任何插件都将作为Cocoapods添加。 In theory, it should be possible to manually merge those in as well, but that becomes much more specific to the plugin itself. 从理论上讲,也应该可以手动将它们合并,但这对于插件本身来说更加具体。
  5. Bitcode is disabled for every target in your project. 项目中的每个目标都禁用了位码。 This is a requirement to link with the Flutter Engine. 这是与Flutter Engine链接的要求。
  6. Generated.xcconfig (containing Flutter-specific environment varaibles) is included in the release and debug .xcconfig files that Cocoapods generates. Cocoapods生成的发行版和调试.xcconfig文件中包含Generated.xcconfig(包含Flutter特定的环境变量)。

The build phase script (xcode_backend.sh) is ensuring that the binaries you build stay up to date with the Dart code that's actually in the folder. 构建阶段脚本(xcode_backend.sh)确保所构建的二进制文件与文件夹中实际存在的Dart代码保持最新。 It also attempts to respect your build configuration setting once this pull request lands (which already did!). 一旦拉入请求成功,它也会尝试遵循您的构建配置设置。

Write code to use FlutterViewController from your host app The proper place to do this will be specific to your host app. 编写代码以从主机应用程序使用FlutterViewController。执行此操作的适当位置将特定于主机应用程序。 Here is an example that makes sense for the blank screen of the host app generated by Xcode 10.0. 这是一个由Xcode 10.0生成的宿主应用程序的空白屏幕有意义的示例。

First declare your app delegate to be a subclass of FlutterAppDelegate . 首先,将您的应用程序委托声明为FlutterAppDelegate的子类。

In AppDelegate.h : AppDelegate.h

#import <UIKit/UIKit.h>
#import <Flutter/Flutter.h>

@interface AppDelegate : FlutterAppDelegate
@end

This allows AppDelegate.m to be really simple, unless your host app needs to override other methods here: 这使AppDelegate.m变得非常简单,除非您的宿主应用需要在此处覆盖其他方法:

#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h> // Only if you have Flutter Plugins

#include "AppDelegate.h"

@implementation AppDelegate

// This override can be omitted if you do not have any Flutter Plugins.
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

If you are writing in Swift, you can do the following in your AppDelegate.swift: 如果使用Swift编写,则可以在AppDelegate.swift:执行以下操作AppDelegate.swift:

import UIKit
import Flutter
import FlutterPluginRegistrant // Only if you have Flutter Plugins.

@UIApplicationMain
class AppDelegate: FlutterAppDelegate {

  // Only if you have Flutter plugins.
  override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    GeneratedPluginRegistrant.register(with: self);
    return super.application(application, didFinishLaunchingWithOptions: launchOptions);
  }

}

....... .......

#import <Flutter/Flutter.h>
#import "ViewController.h"

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button addTarget:self
               action:@selector(handleButtonAction)
     forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"Press me" forState:UIControlStateNormal];
    [button setBackgroundColor:[UIColor blueColor]];
    button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
    [self.view addSubview:button];
}

- (void)handleButtonAction {
    FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
    [self presentViewController:flutterViewController animated:false completion:nil];
}
@end

Or, using Swift: 或者,使用Swift:

ViewController.swift:

import UIKit
import Flutter

class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    let button = UIButton(type:UIButtonType.custom)
    button.addTarget(self, action: #selector(handleButtonAction), for: .touchUpInside)
    button.setTitle("Press me", for: UIControlState.normal)
    button.frame = CGRect(x: 80.0, y: 210.0, width: 160.0, height: 40.0)
    button.backgroundColor = UIColor.blue
    self.view.addSubview(button)
  }

  @objc func handleButtonAction() {
    let flutterViewController = FlutterViewController()
    self.present(flutterViewController, animated: false, completion: nil)
  }
}

You should now be able to build and launch MyApp on the Simulator or on a device. 现在,您应该能够在模拟器或设备上构建并启动MyApp。 Pressing the button should bring up a full-screen Flutter view with the standard Flutter Demo counting app. 按下按钮应使用标准Flutter Demo计数应用程序调出全屏Flutter视图。 You can use routes to show different widgets at different places in your app, as described in the Android section above. 您可以使用路线在应用程序的不同位置显示不同的小部件,如上面的Android部分所述。 To set the route, call 要设置路线,请致电

Objective-C: 目标C:

[flutterViewController setInitialRoute:@"route1"];

Swift: 迅速:

flutterViewController.setInitialRoute("route1")

immediately after construction of the FlutterViewController (and before presenting it). FlutterViewController构建之后立即进行FlutterViewController (并在展示之前)。

You can have the Flutter app dismiss itself by calling SystemNavigator.pop() in the Dart code. 您可以通过在Dart代码中调用SystemNavigator.pop()使Flutter应用自行关闭。

Building and running your app 生成并运行您的应用

You build and run MyApp using Xcode in exactly the same way that you did before you added the Flutter module dependency. 您使用Xcode构建和运行MyApp的方式与添加Flutter模块依赖项之前的方式完全相同。 The same goes for editing, debugging, and profiling your iOS code. 编辑,调试和分析iOS代码也是如此。

Hot restart/reload and debugging Dart code 热重启/重新加载和调试Dart代码

Connect a device or launch a Simulator. 连接设备或启动模拟器。 Then make Flutter CLI tooling listen for your app to come up: 然后使Flutter CLI工具监听您的应用程序:

$ cd some/path/my_flutter
$ flutter attach
Waiting for a connection from Flutter on iPhone X...

Launch MyApp in debug mode from Xcode. 从Xcode以调试模式启动MyApp Navigate to an area of the app that uses Flutter. 导航到使用Flutter的应用程序区域。 Then turn back to the terminal, and you should see output similar to the following: 然后回到终端,您应该看到类似于以下内容的输出:

Done.
Syncing files to device iPhone X...                          4.7s

🔥  To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
An Observatory debugger and profiler on iPhone X is available at: http://127.0.0.1:54741/
For a more detailed help message, press "h". To quit, press "q".

You can now edit the Dart code in my_flutter , and the changes can be hot reloaded by pressing r in the terminal. 现在,您可以在my_flutter编辑Dart代码,然后可以通过在终端中按r来重新加载更改。 You can also paste the URL above into your browser to use the Dart Observatory for setting breakpoints, analyzing memory retention and other debugging tasks. 您也可以将上面的URL粘贴到浏览器中,以使用Dart Observatory设置断点,分析内存保留和其他调试任务。

Debugging specific instances of Flutter 调试Flutter的特定实例

It's possible to add multiple instances of Flutter ( root isolates ) to an app. 可以向应用程序添加Flutter( root isolates )的多个实例。 flutter attach connects to all of the available isolates by default. 默认情况下, flutter attach连接到所有可用的隔离。 Any commands sent from the attached CLI are then forwarded to each of the attached isolates. 然后,将从附加的CLI发送的所有命令转发到每个附加的隔离。

List all attached isolates by typing l from an attached flutter CLI tool. 通过从附加的flutter CLI工具中键入l列出所有附加的分离株。 If unspecified, isolate names are automatically generated from the dart entry point file and function name. 如果未指定,将从dart入口点文件和函数名称自动生成隔离名称。

Example l output for an application that's displaying two Flutter isolates simultaneously: 示例l输出的应用程序同时显示两个Flutter隔离:

Connected views:
  main.dart$main-517591213 (isolates/517591213)
  main.dart$main-332962855 (isolates/332962855)
  1. Attach to specific isolates instead in two steps: 分两步附加到特定的隔离株:

Name the Flutter root isolate of interest in its Dart source. 在Dart来源中命名感兴趣的Flutter根分离株。

// main.dart
import 'dart:ui' as ui;

void main() {
  ui.window.setIsolateDebugName("debug isolate");
  // ...
}
  1. Run flutter attach with the --isolate-filter option. 使用--isolate-filter选项运行flutter attach --isolate-filter

$ flutter attach --isolate-filter='debug'

Waiting for a connection from Flutter...
Done.
Syncing files to device...      1.1s

🔥  To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
An Observatory debugger and profiler is available at: http://127.0.0.1:43343/
For a more detailed help message, press "h". To detach, press "d"; to quit, press "q".

Connected view:
  debug isolate (isolates/642101161)

Another feature still in experimental I found that may interest you is Obfuscating dart code 仍处于实验阶段的另一个功能我发现您可能会感兴趣的是混淆Dart代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM