gpt4 book ai didi

android - 在Flutter项目上创建Android库

转载 作者:行者123 更新时间:2023-11-29 14:34:41 25 4
gpt4 key购买 nike

我正在尝试在flutter项目之上创建一个android库以进行分发。我使用flutter开发了一个应用程序,但我想将其包装在Android库中。我一直收到错误消息Transform output file /Users/Dev/Documents/projects/LibExample/testlib/build/intermediates/flutter/flutter-x86.jar does not exist.我已经阅读了几乎所有在线搜索内容,但到目前为止没有任何内容。

LibExample是我使用该库的示例应用程序,而testlib是Android库。在testlib中,我设置了build.graddle来找到flutter.sdk。我还指定了颤振源的位置。每当我sync gradle文件时,都会收到错误/Users/Dev/Documents/projects/LibExample/testlib/build/intermediates/flutter/flutter-x86.jar不存在。
`

这是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.

最佳答案

我最终在一个颤抖的维基page上偶然发现了此功能。
撰写本文时要注意的一件非常重要的事情;

“ add2app”支持处于预览状态,到目前为止仅在主频道上可用。

尽管此功能仍处于试验阶段,但可以正常工作(很少遇到这种情况,例如从Android主机调用时启动flutter应用程序所需的时间)。

使用flutter create xxx创建的Flutter项目包括用于Flutter / Dart代码的非常简单的宿主应用程序(单个Activity Android宿主和单个ViewController iOS宿主)。您可以修改这些主机应用程序以适合您的需求并从那里构建。

但是,如果您要从任一平台的现有主机应用程序开始,则可能需要将Flutter项目作为某种形式的库包含在该应用程序中。

这就是Flutter模块模板所提供的。执行flutter create -t module xxx会产生一个Flutter项目,其中包含一个Android库和一个Cocoapods Pod,供您的现有主机应用程序使用。

安卓系统

创建Flutter模块
假设您在some / path / MyApp上有一个现有的Android应用程序,并且希望Flutter项目作为同级项目:

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


这将创建一个 some/path/my_flutter/ Flutter模块项目,其中包含一些Dart代码以帮助您入门,以及一个 .android/隐藏的子文件夹,该文件夹将模块项目包装在Android库中。

(尽管随后不需要,但如果您愿意,可以使用Gradle构建该库:

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


这样会在 flutter-debug.aar中生成一个 .android/Flutter/build/outputs/aar/.存档文件

使主机应用程序依赖Flutter模块

将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


绑定和脚本评估允许Flutter模块本身为 include(作为 :flutter)以及该模块使用的任何Flutter插件(例如 :package_info:video_player等)在您的 settings.gradle评估上下文中。

在您的应用中引入对Flutter模块的 implementation依赖项:

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


使用Java代码中的Flutter模块

使用Flutter模块的Java API将Flutter视图添加到您的主机应用程序。这可以通过直接使用 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);
}
});


也可以创建一个 FlutterFragment来单独负责生命周期的工作:

// 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();
}
});


在上方,我们使用字符串 "route1"告诉Dart代码在Flutter视图中显示哪个窗口小部件。 Flutter模块项目模板的 lib/main.dart文件应位于(或以其他方式解释)所提供的路由字符串(可作为 switch使用)上的 window.defaultRouteName,以确定要创建并传递给 runApp的小部件。示意地

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),
);
}
}


路由字符串以及如何解释字符串完全取决于您。

生成并运行您的应用

生成和运行 MyApp的方式与添加Flutter模块依赖项之前的方式完全相同,通常使用Android Studio。编辑,调试和分析Android代码也是如此。

热重启/重新加载和调试Dart代码

正在进行全面的IDE集成以支持与混合应用程序的Flutter / Dart代码一起使用。但是基本原理已经通过Flutter命令行工具和Dart Observatory Web用户界面提供。

连接设备或启动仿真器。然后使Flutter CLI工具监听您的应用程序:

$ cd some/path/my_flutter
$ flutter attach


正在等待Nexus 5X上Flutter的连接...
在Android Studio中以调试模式启动 MyApp(或您通常采用的任何一种方式)。导航到使用Flutter的应用程序区域。然后回到终端,您应该看到类似于以下内容的输出:

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".


现在,您可以在 my_flutter中编辑Dart代码,并且可以通过在终端中按 r来热加载更改。您也可以将上面的URL粘贴到浏览器中,以使用Dart Observatory设置断点,分析内存保留和其他调试任务。

的iOS
创建Flutter模块

假设您在 some/path/MyApp上有一个现有的iOS应用程序,并且希望Flutter项目作为同级项目:

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


这将创建一个 some/path/my_flutter/ Flutter模块项目,其中包含一些Dart代码以帮助您入门,以及一个 .ios/隐藏的子文件夹,该文件夹包含包含一些Cocoapods和一个辅助Ruby脚本的模块项目。

使主机应用程序依赖Flutter模块

下面的描述假定您现有的iOS应用程序具有与要求Xcode版本10.0使用Objective-C生成新的“单视图应用程序”项目所得到的结构类似的结构。如果您现有的应用程序具有不同的文件夹结构和/或现有的 .xcconfig文件,则可以重用它们,但是可能需要相应地调整下面提到的一些相对路径。

假定的文件夹结构如下:

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


将Flutter应用添加到Podfile

集成Flutter框架需要使用CocoaPods依赖关系管理器。这是因为Flutter框架也需要对my_flutter中可能包含的所有Flutter插件可用。

如果需要,请参阅 cocoapods.org了解如何在您的开发计算机上安装CocoaPods。

如果您的主机应用程序( MyApp)已在使用Cocoapods,则只需执行以下操作即可与您的 my_flutter应用程序集成:

将以下行添加到您的 Podfile

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


运行 pod install

每当在 some/path/my_flutter/pubspec.yaml中更改Flutter插件依赖项时,都需要运行从 some/path/my_flutter获取的flutter软件包以刷新 podhelper.rb脚本读取的插件列表。然后从 some/path/MyApp再次运行pod install。

podhelper.rb脚本将确保将插件和Flutter.framework添加到项目中,并确保所有目标均禁用了位码。

添加用于构建Dart代码的构建阶段

在“项目”导航器中选择顶级 MyApp项目。在主视图的左侧选择TARGET MyApp,然后选择 Build Phases选项卡。通过单击主视图左上方的 +,添加一个新的构建阶段。选择 New Run Script相位。展开新的 Run Script,将其添加到阶段列表中。

将以下内容粘贴到“外壳”字段下方的文本区域中:

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


最后,将新的构建阶段拖到“目标依赖项”阶段之后。

现在,您应该可以使用 ⌘B构建项目。

引擎盖下
如果您出于某种原因手动执行此操作或调试为什么这些步骤无法执行,请执行以下操作:


Flutter.framework(引擎库)已嵌入到您的
适用于您的应用。这必须与发布类型匹配
(调试/配置文件/发行版)以及您应用的架构
(arm *,i386,x86_64等)。 Cocoapods作为供应商将其引入
框架,并确保将其嵌入到您的本机应用程序中。
App.framework(您的Flutter应用程序二进制文件)已嵌入
您的应用。
flutter_assets文件夹将作为资源嵌入-它
包含字体,图像,并且在某些构建模式下还包含
引擎在运行时所需的二进制文件。这个问题
文件夹可能会导致运行时错误,例如“无法为之运行引擎
配置”-通常表示该文件夹不是
被嵌入,或者您试图与
一个启用AOT的引擎,反之亦然!
任何插件都将作为Cocoapods添加。从理论上讲,应该
也可以手动合并它们,但这变得很多
更特定于插件本身。
项目中的每个目标都禁用了位码。这是一个
与Flutter Engine链接的要求。
Generated.xcconfig(包含Flutter特定的环境
变量)包含在发行版和调试.xcconfig文件中,
椰子足产生。


构建阶段脚本(xcode_backend.sh)确保所构建的二进制文件与文件夹中实际存在的Dart代码保持最新。一旦 this pull request登陆,它也会尝试遵循您的构建配置设置(已经这样做了!)。

编写代码以从主机应用程序使用FlutterViewController
正确的位置将取决于您的主机应用程序。这是一个由Xcode 10.0生成的宿主应用程序的空白屏幕有意义的示例。

首先,将您的应用程序委托声明为 FlutterAppDelegate的子类。

AppDelegate.h中:

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

@interface AppDelegate : FlutterAppDelegate
@end


这使 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


如果您是用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


或者,使用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)
}
}


现在,您应该能够在模拟器或设备上构建并启动MyApp。按下按钮应使用标准Flutter Demo计数应用程序调出全屏Flutter视图。您可以使用路线在应用程序的不同位置显示不同的小部件,如上面的Android部分所述。要设置路线,请致电

目标C:

[flutterViewController setInitialRoute:@"route1"];


迅速:

flutterViewController.setInitialRoute("route1")


在构造 FlutterViewController之后(并在展示之前)立即使用。

您可以通过在Dart代码中调用 SystemNavigator.pop()来关闭Flutter应用。

生成并运行您的应用

您使用Xcode构建和运行MyApp的方式与添加Flutter模块依赖项之前的方式完全相同。编辑,调试和分析iOS代码也是如此。

热重启/重新加载和调试Dart代码

连接设备或启动模拟器。然后使Flutter CLI工具监听您的应用程序:

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


从Xcode以调试模式启动 MyApp。导航到使用Flutter的应用程序区域。然后回到终端,您应该看到类似于以下内容的输出:

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".


现在,您可以在 my_flutter中编辑Dart代码,并且可以通过在终端中按 r来热加载更改。您也可以将上面的URL粘贴到浏览器中,以使用Dart Observatory设置断点,分析内存保留和其他调试任务。

调试Flutter的特定实例

可以向应用程序添加Flutter( root isolates)的多个实例。 flutter attach默认情况下连接到所有可用的隔离。然后,将从附加的CLI发送的所有命令转发到每个附加的隔离。

通过从附加的 l CLI工具中键入 flutter列出所有附加的隔离株。如果未指定,将从dart入口点文件和函数名称自动生成隔离名称。

同时显示两个Flutter隔离的应用程序的示例 l输出:

Connected views:
main.dart$main-517591213 (isolates/517591213)
main.dart$main-332962855 (isolates/332962855)



分两步附加到特定的隔离株:


在Dart来源中命名感兴趣的Flutter根分离株。

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

void main() {
ui.window.setIsolateDebugName("debug isolate");
// ...
}



使用 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)


我发现您可能会感兴趣的另一个功能是 Obfuscating dart code

关于android - 在Flutter项目上创建Android库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53164519/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com