如何生成一个可以在没有带反应原生的服务器的情况下运行的apk?

时间:2016-03-11 08:02:10

标签: javascript android react-native mobile-application

我已经构建了我的应用程序,我可以在我的本地模拟器上运行它(也可以通过更改调试服务器在同一网络中的我的Android设备上运行)。

但是,我想构建一个apk,我可以发送给没有访问开发服务器的人,我希望他们能够测试应用程序。

我看到在文档的iOS部分有一个使用脱机捆绑的部分。但我无法弄清楚如何为Android做同样的事情。这可能吗?如果是这样,怎么样?

更新:关于这个问题(react native android failed to load JS bundle)的答案,据说可以从开发服务器下载离线包。但是当我从开发服务器获取捆绑包时,无法加载图像文件。

21 个答案:

答案 0 :(得分:160)

您必须创建一个密钥来签署apk。使用以下方法创建密钥:

 keytool -genkey -v -keystore my-app-key.keystore -alias my-app-alias -keyalg RSA -keysize 2048 -validity 10000

提示时使用密码

生成密钥后,使用它生成可安装的版本:

 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/

使用gradle生成构建

 cd android && ./gradlew assembleRelease

将APK上传到手机。 -r标志将替换现有应用程序(如果存在)

adb install -r ./app/build/outputs/apk/app-release-unsigned.apk

此处提到了更详细的说明:https://facebook.github.io/react-native/docs/signed-apk-android.html

更新:根据@shashuec和@Fallen的评论

如果您收到错误

  

ENOENT:没有这样的文件或目录,打开'android / app / src / main / assets / index.android.bundle'

运行mkdir android / app / src / main / assets

答案 1 :(得分:113)

根据Aditya Singh的回答,生成的(未签名的)apk不会安装在我的手机上。我必须使用说明here生成签名的apk。

以下对我有用:

<?php
session_start();
?>

<html>
<head>

            <!--Chat name -->
<?php
if(isset($_SESSION["steamname"])){

$user = $_SESSION["steamname"];

}

else {
    $user = "";
}
?>

    <title>CSGORised - Coinflip</title>
    <link href="css/style.css" type="text/css" rel="stylesheet">
    <link href='http://fonts.googleapis.com/css?
 family=Open+Sans:400,300,600,700,800' rel='stylesheet' type='text/css'>
    <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="Chat.js"></script>
    <link href="https://fonts.googleapis.com/css?family=Passion+One" 
rel="stylesheet">
    <script src="ChatPoster.php"></script>
    <link rel="stylesheet" 
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-
awesome.min.css">
    <script src="GetMessages.php"></script>
    <script src="openid/openid.php"></script>
    <link href="https://fonts.googleapis.com/css?family=Fjalla+One" 
rel="stylesheet">
    <script src="createGame.js"></script>


</head>


<body>


<div id="displaybar">
</div>




    <style>

    .session-steam-id {
    position: fixed;
    top: 158px;
    left: 87px;
    width: 165px;
    padding: 0;
    border: none;
    background: none;
    font-size:30px;
    font-family: 'Fjalla One', sans-serif;
    color: #b107b7;
    text-decoration: none
    }



     .steam-pic {
     border-radius: 50%;
     position: fixed;
     top: 150px;
     left: 28px;
     height: 50px;
     width: 50px;
     align-content: center;
    }

    </style>


    <div id="rectangle"></div>
    <div id="toolbar">
        <?php if(isset($_SESSION["steamname"]))
        //If steamname not equals 0
            {   

                     echo '<a class="button-logout" 
href="steamauth/logout.php">Log Out</a>';

                }
            else
                {
                    echo '<a class="button-login" 
href="steamauth/login_steam.php">Log In</a>';

                }
        ?>

    </div>
    <?php
    $steamphoto = $_SESSION["profileimg"];
    ?>


    <div id="top6"></div>
    <div id="top1"></div>
    <div id="toolbar2">
            <?php if(isset($_SESSION["steamname"]))
        //If steamname not equals 0
            {   
                echo "<img class=\"steam-pic\" src='$steamphoto'>";
                echo "<div class=\"session-steam-id\">$user</div>"; 
            }
            else {
                '';
            } ?>



    </div>


    <h1>CSGORised</h1>


                <!--The side buttons-->

    <div>   

    <a class="button-support" href="etc/support.php">Support</a>
    <a class="button-FAQ" href="etc/FAQ.php">FAQ</a>
    <a class="button-Provably-fair" href="etc/provablyfair.php">Provably 
Fair</a>
    <a class="button-about-us" href="etc/aboutus.php">About us</a>
    <a class="button-terms-and-co" href="etc/tandc.php">Terms and 
Conditions</a>
    <a class="button-entertainment" 
href="etc/entertainment.php">Entertainment</a>


    </div>

            <!--End of the side buttons-->

    <div style="text-align: center"><a 
href="https://youtube.com/garlicyvideos"target="_blank"><img class="img-
youtube" src=https://developers.google.com/youtube/images/YouTube-icon-
full_color.png alt="Garlicvideos's Youtube" height="42" breadth="42"/></a>
</div>

    <div style="text-align: center"><a 
href="https://www.instagram.com/csgorised"target="_blank"><img class="img-
instagram" 
src=http://www.stickpng.com/assets/images/580b57fcd9996e24bc43c521.png 
alt="Our Official Instagram!" height="42" breadth="42"/></a></div>

    <div class='chatContainer' style="position: fixed;">
        <div class='chatMessages'></div>
        <div class='chatbottom'>
            <form action='#' onSubmit='return false;' id='chatForm'>
                <input type='hidden' id='name' value='<?php echo $user ?>' 
/>
                <input type='text' name='text' id='text' value='' 
placeholder='Say something
                ' />
                <input type='submit' name='<i>submit</i>' value='Say' />
                </form>

    </div>
</div>


</body>
</html>

$ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000 文件放在my-release-key.keystore下     项目文件夹中的目录。然后编辑该文件     android/app并添加以下内容(替换****     使用正确的密钥库密码,别名和密钥密码)

~/.gradle/gradle.properties

如果您正在使用MacOS,则可以使用说明here将密码存储在钥匙串中,而不是将其存储在纯文本中。

然后编辑app / build.gradle并确保存在以下内容(可能需要添加具有signingConfigs signingConfig的部分):

MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=****
MYAPP_RELEASE_KEY_PASSWORD=****

然后运行命令... android { ... defaultConfig { ... } signingConfigs { release { if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) { storeFile file(MYAPP_RELEASE_STORE_FILE) storePassword MYAPP_RELEASE_STORE_PASSWORD keyAlias MYAPP_RELEASE_KEY_ALIAS keyPassword MYAPP_RELEASE_KEY_PASSWORD } } } buildTypes { release { ... signingConfig signingConfigs.release } } } ...

适用于Windows &#39; cd android&#39;然后运行cd android && ./gradlew assembleRelease命令,在gradlew assembleRelease下找到签名 apk

答案 2 :(得分:25)

你应该只使用android studio来完成这个过程。它更简单。但首先在您的react本机app目录中运行此命令:

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/

然后使用android studio打开你在本机应用程序目录中的'android'文件夹,它会要求升级gradle和其他一些东西。去建立 - &gt;生成已签名的APK并按照其中的说明操作。这真的很直接。

答案 3 :(得分:24)

运行此命令:

react-native run-android --variant=release
  

请注意--variant=release仅在您设置签名时可用   与cd android && ./gradlew assembleRelease

答案 4 :(得分:15)

用于React Native 0.49及以上

你应该去终端上的项目目录并运行该命令

1 - mkdir android/app/src/main/assets
2 - 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

如果低于0.49

  1 - mkdir android/app/src/main/assets
  2 - 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

然后使用android studio打开&#39; android&#39;你在文件夹中反应原生app目录,它会要求升级gradle和其他一些东西。去建立 - &gt;生成已签名的APK并按照其中的说明操作。那个okey。

答案 5 :(得分:11)

如果你得到Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]

我尝试使用@ Aditya生成未签名的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.bu‌​ndle --assets-dest android/<your-package-name>/src/main/res/ 

2)从Android Studio生成已签名的APK文件。

3)将已签名的APK文件安装到USB设备:

adb -d install -r <path_to_signed_apk> 

-d标志只是告诉adb安装在附加的USB设备上,如果您还运行了模拟器。如果要在任何模拟器上安装,请删除-d标志。

4)利润!

答案 6 :(得分:5)

我有另一个解决方案: - 生成签名密钥 您可以使用keytool生成私有签名密钥。在Windows上,必须从C:\ Program Files \ Java \ jdkx.x.x_x \ bin运行keytool。

$ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

将my-release-key.keystore文件放在项目文件夹中的android / app目录下。

编辑项目文件夹中的文件android / app / build.gradle并添加签名配置

android {
....
signingConfigs { 
  release { 

      storeFile file('my-release-key.keystore') 
      storePassword 'yourpassword' 
      keyAlias 'my-key-alias' 
      keyPassword 'yourpassword' 

  } 
}}}


buildTypes {release {signingConfig signingConfigs.release}}

并运行

gradlew assembleRelease

这将在android \ app \ build \ outputs \ apk中提供两个文件 app-release.apk和app-release-unsigned.apk 现在在你的Android设备上安装app-release.apk。

答案 7 :(得分:5)

如果任何人都想在没有Playstore密钥的情况下进行构建,那么此命令将非常有帮助。

# react-native run-android --variant=release

构建完成后,您可以在发行版本的构建文件中找到apk。

答案 8 :(得分:4)

如果遇到涉及index.android.js的错误。这是因为您使用的是新的React-native版本(我使用的是0.55.4) 只需将“ index.android.js”替换为“ index.js”

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/

答案 9 :(得分:4)

转到项目目录并运行命令:

cd android && ./gradlew assembleRelease

答案 10 :(得分:2)

enter image description here

enter image description here

  • 一些对 WINDOW 用户有用的脚本

将这些代码复制粘贴到 "script":{}

下的 package.json 文件中
 * VS Code
   --Enable NPM SCRIPT

   --Now you can directly run scripts from here


    "android": "react-native run-android",
    "clean-run-android": "cd android && ./gradlew clean && cd.. && react-native run-android  ",
    "start": "node node_modules/react-native/local-cli/cli.js start --reset-cache",
    "reset": "rm -rf node_modules/ && npm cache clear && watchman watch-del-all && npm i",
    "debug-build": "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/ && cd android && ./gradlew assembleDebug && cd app/src/main/res/ && rmdir /S /Q raw && rmdir /S /Q drawable-mdpi",
    "release-build": "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/build/intermediates/res/merged/release/ && cd android && ./gradlew assembleRelease && cd..",
    "install-apk": "cd android && ./gradlew installRelease",
    "release-aab": "cd android && ./gradlew bundleRelease"

答案 11 :(得分:1)

希望它将对新手有所帮助

官方文档here

如果您没有密钥存储区,而不是在命令之前使用,否则跳过

生成签名密钥/密钥库文件 您可以使用keytool生成专用签名密钥。在Windows上,必须从C:\ Program Files \ Java \ jdkx.x.x_x \ bin运行keytool。

$ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

您将获得类似 my-release-key.keystore

的文件

设置gradle变量 将my-release-key.keystore文件放置在项目文件夹中的android / app目录下。 编辑文件android / gradle.properties并添加以下内容(用正确的密钥库密码,别名和密钥密码替换*****), enableAapt2 set false是解决方法,因为android gradle版本3.0 problem

MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=*****
MYAPP_RELEASE_KEY_PASSWORD=*****

android.enableAapt2=false

然后添加这些app / buid.gradle(应用程序)

低于默认配置

signingConfigs {
        release {
            if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
                storeFile file(MYAPP_RELEASE_STORE_FILE)
                storePassword MYAPP_RELEASE_STORE_PASSWORD
                keyAlias MYAPP_RELEASE_KEY_ALIAS
                keyPassword MYAPP_RELEASE_KEY_PASSWORD
            }
        }

和Inside Build类型发布{}

 signingConfig signingConfigs.release

然后只需在android studio终端中运行此命令 下面的命令将自动在所有答案之上

如果是Windows

cd android
gradlew assembleRelease

如果是linux / mac

$ cd android
$ ./gradlew assembleRelease

如果遇到任何错误,请删除所有构建文件夹并运行命令

gradlew clean

再来一次

gradlew assembleRelease

答案 12 :(得分:1)

获取最新的React Native版本以捆绑项目

Android

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/

iOS

react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios

答案 13 :(得分:0)

使用android studio为react的android项目生成签名的apk也是一个好方法,在android studio中打开react的android项目并生成击键和签名的apk。

答案 14 :(得分:0)

Android Studio中的GUI方式

  • 已在Android Studio中打开React Native应用程序的Android应用程序部分(这仅意味着使用Android Studio打开您的react-native项目的android文件夹)
  • 转到顶部的“构建”标签
  • 转到“构建捆绑包/ APK”
  • 然后选择“构建APK”
  • 这将引导您完成查找密钥以签名APK或创建密钥(如果您还没有密钥)的过程,这非常简单。如果您只是在练习,则可以生成这些密钥并将其保存到桌面。
  • 该过程完成后,如果构建成功,Android Studio下面将弹出一个弹出窗口。点击其中的“定位”(APK)链接
  • 这将带您进入apk文件,将其移至您的android设备。然后在Android设备上导航至该文件并安装。

答案 15 :(得分:0)

请参阅本机有关生成签名APK的官方文档

React-Native Generating Signed APK

答案 16 :(得分:0)

尝试以下方法,它将在您的root / android / app / build / outputs / apk / debug文件夹中生成一个app-debug.apk

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

然后转到android文件夹并运行

./gradlew assembleDebug

答案 17 :(得分:0)

无需开发服务器即可生成调试 APK

如果你真的想生成一个可以在没有开发服务器的情况下运行的调试 APK(用于测试目的),这是我对另一篇类似帖子的回答的链接,它可能对你有帮助。
https://stackoverflow.com/a/65762142/7755579

你所要做的就是:

  1. 编辑android/app/build.gradle
project.ext.react = [
    ...
    bundleInDebug: true, // add this line
]
  1. 在项目的根目录运行此命令
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
  1. 然后,在 ./gradlew assembleDebug 文件夹中运行 gradlew assembleDebug(Mac 或 Linux)或 /android (Windows)
    如果构建失败,我建议您从 Android Studio 构建应用

答案 18 :(得分:0)

第一次

cd android

然后运行

./gradlew installRelease

最后,您将可以在这里找到该 apk。

Project\android\app\build\outputs\apk\release\app-release.apk

答案 19 :(得分:0)

对我来说 ./gradlew assembleRelease 不再有效,但以下有效。

./gradlew :app:assembleRelease

感谢this comment

答案 20 :(得分:-1)

我面临发布的问题,经过2天的努力工作,我解决了这个问题,并在所有地方搜索了答案,但没有积极的结果... 问题是我在制作整个项目后试图发布APK,如果我不在手机上运行,​​我试图在其他手机上运行的发布apk导致失败... 之后,我开始一个新项目,并在每次迭代或更改代码后逐步进行操作,然后使用gradlew assembleReference制作并升级该APK,从而使我获得成功...