如何在android上使用离线捆绑? 我没有在android上看到关于使用offline bundle的文档。 我试图取消注释build.gradle中的代码。
project.ext.react = [
// the name of the generated asset file containing your JS bundle
bundleAssetName: "index.android.bundle",
// the entry file for bundle generation
entryFile: "index.android.js",
// whether to bundle JS and assets in debug mode
bundleInDebug: false,
// whether to bundle JS and assets in release mode
bundleInRelease: true,
// the root of your project, i.e. where "package.json" lives
root: "../../",
// where to put the JS bundle asset in debug mode
jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
// where to put the JS bundle asset in release mode
jsBundleDirRelease: "$buildDir/intermediates/assets/release",
// where to put drawable resources / React Native assets, e.g. the ones you use via
// require('./image.png')), in debug mode
resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
// where to put drawable resources / React Native assets, e.g. the ones you use via
// require('./image.png')), in release mode
resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
// by default the gradle tasks are skipped if none of the JS files or assets change; this means
// that we don't look at files in android/ or ios/ to determine whether the tasks are up to
// date; if you have any other folders that you want to ignore for performance reasons (gradle
// indexes the entire tree), add them here. Alternatively, if you have JS files in android/
// for example, you might want to remove it from here.
inputExcludes: ["android/**", "ios/**"]
]
但它没有用。它仍然从服务器获取JS包。 我错过了什么吗?
要将JS脱机捆绑到android中,首先在各自的项目路径中启动服务器:
react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
您可以阅读react.gradle
的源代码,然后您将了解如何进行离线捆绑。
在react.gradle
中,它为每个构建变量创建离线bundle gradle任务,并使其在gradle进程资源之前执行,但它在一些特殊条件下启用bundle任务,代码为:
enabled config."bundleIn${targetName}" ||
config."bundleIn${buildTypeName.capitalize()}" ?:
targetName.toLowerCase().contains("release")
而config
对象实际上是react
对象,因为它的定义是def config = project.hasProperty("react") ? project.react : [];
而targetName
的定义是def targetName = "${productFlavorName.capitalize()}${buildTypeName.capitalize()}"
因此,如果我们在react
中定义了正确的app\build.gradle
属性,我们就可以启用离线捆绑任务。
例如,如果我们想在release
构建类型中启用离线束而不在debug
构建类型中启用离线束,我们可以将react
定义为:
ext.react = [
bundleInDebug : false,
bundleInRelease : true
]
然后在命令行中执行gradle assembleRelease
,gradle将执行bundle任务,js包将包含在最终的apk中。
现在在您的问题中,您已经定义了正确的react
对象,但是您没有提到您运行的构建类型。只执行gradle assembleRelease
可以做捆绑工作,也许你执行gradle assembleDebug
所以它没有任何意义。
还有一个我需要说的问题(另见issue7258)。如果您为发布版本类型启用了捆绑任务并从android studio运行应用程序,则gradle不执行bundleReleaseJsAndAssets
,因为android studio默认启用功能Configure on demand
(它在文件|设置|构建,执行,部署|编译器中)以加速在构建时,在react.gradle
中,当所有项目都配置(或称为已评估)时,bundle任务将添加到项目中,因为主代码位于gradle.projectsEvaluated{}
块中。
按需配置模式尝试仅配置与请求的任务相关的项目,即它仅执行参与构建的项目的build.gradle文件。
由于一些不明原因,启用gradle.projectsEvaluated{}
功能时,Configure on demand
块中定义的任何任务都不会执行。要使其可执行,请在android studio设置中禁用Configure on demand
功能,或将gradle.projectsEvaluated{}
更改为afterEvaluate{}
。
如果你在命令行工具中运行gradle assembleRelease
,一切都很好,因为默认情况下禁用Configure on demand
。
您不必在gradle.build文件中取消注释任何内容。它可供参考,如果需要,您可以覆盖任何默认值。
问题是Android Studio没有运行负责生成捆绑的任务。
要在Android Studio中修复此问题,请转到Preferences > Build, Execution, Deployment > Build Tools > Compiler
并取消选中"Configure on demand"
。
现在,您标记为需要捆绑包的任何变体都将自动生成捆绑包。
默认情况下,调试变量不会生成包:bundleInDebug : false
你可以这样改变。在这里,我还提供了如何更改入口点的默认位置和捆绑包的默认名称的示例。
project.ext.react = [
bundleAssetName: "index.myapp.bundle",
entryFile: "js/index.myapp.js",
bundleInDebug: true
]
一旦进行了这些调整,您仍然可能会陷入问题构建,因为Studio无法识别您的shell配置文件中的路径,因此我可能找不到节点的路径。
I posted a solution to that issue here
这是一个稳定而强大的解决方案。在环境中进行这些更改后,您无需手动执行任何操作。当您按下IDE中的按钮时,将自动构建Bundle,允许您选择正确的构建变体(也在Studio窗口的LHS栏上的IDE中朝向底部)。
当通过create-react-native-app创建一个未签名的apk来反应本机项目时,它没有index.android.js和index.ios.js .so首先你必须检查wheter index.js文件是否在那里您的项目。如果它不可用,则创建一个新文件index.js并在那里编写此代码
import { AppRegistry } from "react-native";
import App from "./App";
AppRegistry.registerComponent("VOS", () => App);
在此之后弹出项目,然后运行此命令
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
然后react-native run-android
所以它会为你建立一个apk。
您可以在ReactApplication类中覆盖getJSBundleFile()函数以返回自定义文件路径。
@Nullable
@Override
protected String getJSBundleFile() {
return "/your/bundle/path/bundle.file.name.bundle";
}
之后,只需使用react-native bundle
生成捆绑包,然后将生成捆绑包放入设备的指定路径中。
我尝试使用未签名的APK文件并安装它,但当我在我的Android平板电脑上安装它时,它给了我一个错误的Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]
。
我想这是因为APK文件没有签名,平板电脑对此不满意。因此,在生成React Native捆绑文件后,我能够通过Android Studio正常生成签名的APK文件。
顺便说一句,我们的应用程序是一个功能齐全的Android应用程序,已经存在于Play商店中,我们只是在一口大小的片段中添加React Native,因为它非常棒。
总而言之,这是我的步骤:
1)生成React Native包:
react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/<your-package-name>/src/main/assets/index.android.bundle --assets-dest android/<your-package-name>/src/main/res/
2)从Android Studio生成签名的APK文件。
3)将签名的APK文件安装到USB设备:
adb -d install -r <path_to_signed_apk>
4)利润!