apache / cordova-android

Apache Cordova Android
https://cordova.apache.org/
Apache License 2.0
3.59k stars 1.52k forks source link

Google Play enhanced 64bit build check, how to build without crosswalk for 64bit app bundle? #805

Closed tomriddle1234 closed 4 years ago

tomriddle1234 commented 4 years ago

Bug Report

Problem

Hi, but can someone tell me how to use, Google play just enhanced 64bit check, cordova is not working at all for Android, all my apk get rejected.

I tried,

cordova build android --release --packageType=bundle

cordova build android --bundle

still getting apk instead of aab.

cordova-android installed with

ionic cordova platform add android@https://github.com/apache/cordova-android.git

What is expected to happen?

create the aab file that pass Google Play 64bit and 32bit check.

What does actually happen?

  1. it doesn't build aab, still original apk
  2. the result apk is still 32bit version, not 64bit compatible.

Information

Ionic:

   Ionic CLI                     : 5.2.4 (/usr/local/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.7.4
   @angular-devkit/build-angular : 0.801.3
   @angular-devkit/schematics    : 8.2.1
   @angular/cli                  : 8.1.2
   @ionic/angular-toolkit        : 2.0.0

Cordova:

   Cordova CLI       : 9.0.0 (cordova-lib@9.0.1)
   Cordova Platforms : android 8.1.0-dev, browser 6.0.0
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 4.0.1, (and 10 other plugins)

Utility:

   cordova-res : 0.6.0 
   native-run  : 0.2.8 

System:

   Android SDK Tools : 26.1.1 (/home/tom/Android/Sdk)
   NodeJS            : v12.5.0 (/usr/local/bin/node)
   npm               : 6.10.2
   OS                : Linux 4.15

Command or Code

Environment, Platform, Device

Version information

Checklist

breautek commented 4 years ago

You're right, as of august, google requires apps that includes native libraries to include a 64bit variant of that native code.

I'm not very familiar with Ionic, but of you can provide me a sample repository that reproduces this issue, I can probably look at this issue later tonight.

tomriddle1234 commented 4 years ago

Hi thanks for replying, the Google Play enhanced 64bit check just happened today, it was just warnings, but now it's error.

I am not sure it is about ionic, since I think ionic build just use cordova-android for android, though usually there can be lots of cordova plugins used.

In the current result apk, I check it with Android Studio Apk inspector, there's no arm64 folder in lib.

I have no experience in crosswalk, my current project didn't include it, will this make cordova not compiling 64bit version, can 64bit (just arm64) happen without crosswalk?

I'll try to prepare the repo tomorrow.

breautek commented 4 years ago

A bundle file is very different than an apk file. While using the packageType=bundle flag there will be (or should be) an aab file made in the the outputs/bundle directory.

Also note that

cordova build android --release --packageType=bundle is wrong.

This is correct:

cordova build android --release -- --packageType=bundle

Note the double -- --. This is because --packageType is a platform argument.

tomriddle1234 commented 4 years ago

Cool, it works now. thank you so much.

Just tried the latest cordova-android, with cordova-plugin-ionic4-crosswalk-webview plugin.

And add these settings,

    <preference name="xwalk64bit" value="true" />
    <preference name="xwalkVersion" value="xwalk_core_library:23.53.589.4" />

and change plugins/cordova-plugin-ionic4-crosswalk-webview/src/android/xwalk.gradle like,

    android {
        if (xwalk64bit != null) {
//             productFlavors {
//                 x86_64 {
//                     versionCode defaultConfig.versionCode + 6
//                     ndk {
//                        abiFilters "x86_64", ""
//                     }
//                 }
//                 arm64 {
//                     versionCode defaultConfig.versionCode + 9
//                     ndk {
//                         abiFilters "arm64-v8a", ""
//                     }
//                 }
//             }
        }
    }

Plus

ionic cordova prepare android --prod --release
cordova build android --release -- --packageType=bundle

Then it builds the aab.

tomriddle1234 commented 4 years ago

But I still have question that whether we have to use the old crosswalk to full fill Google Play 64bit requirement ? Can we do that without cross walk?

breautek commented 4 years ago

Crosswalk is a plugin that includes native libraries so having crosswalk requires you to include a 64bit apk (or use a bundle).

Cordova itself does not have any native libraries so Cordova and Cordova and all of cordova-provided plugins are written in non-native code so they automatically passes the 64bit requirement.

Many apps are written entirely in non-native code (e.g. the Java programming language or Kotlin) and do not need code changes.

Citation: Preparing for the 64-bit requirement

So assuming you have no other third party libraries that includes native built libraries, removing crosswalk may remove the requirement of providing a 64bit variant.

On another note that is somewhat unrelated, crosswalk is deprecated, no longer maintained, and their latest version is based off of Chrome 53 which is rather old, so if possible it might be wise to consider removing crosswalk as your android webview.

tomriddle1234 commented 4 years ago

I see, thanks.

With cordova-android 8.0.0, the normal build with cordova build android --release builds only one apk, and it cannot pass Google Play check, saying The following APKs or App Bundles are available to 64-bit devices, but they only have 32-bit native code: 10101.. I don't know this is the issue on the apk or just simply the version number problem.

I have no idea about native Android build scheme, but I feel it might be just a build configuration problem.

I knew crosswalk is old. but many ionic/cordova apps have cordova plugins which have mixing native code/libs, like mine with 7-8 plugins. I could build with crosswalk, get the aab and it passes Google Play check.

janpio commented 4 years ago

I could build with crosswalk, get the aab and it passes Google Play check.

Why don't you do that then?

breautek commented 4 years ago

I do use crosswalk in my plugins still. It is possible to build both a 32bit and a 64bit apk using a multi-apk setup, but the crosswalk plugin requires some changes as they conflict with Cordova configuration. They overwrite cordova's configuration with a configuration that doesn't actually work.

But with Google's new bundle format, you should be able to not worry about that kind of advanced configuration by using the bundle format. There isn't any announced plans but in the future I could foresee Google deprecating the APK format for deployments and forcing everyone use bundles when deploying to the app store. So I would recommend getting onto the bundle format as soon as possible.

A bundle is a format intended to be deployed to the app store, it allows Google to build APKs optimized specifically for the device installing your app. It will simplify your build process significantly.

tomriddle1234 commented 4 years ago

here is some updates on my side.

The app bundle I built with cordova-plugin-ionic4-crosswalk-webview, sometimes cannot install on some phone properly, so that could be the crosswalk maintenance issue.

Just now I removed crosswalk, and with the latest cordova-android code, I had to modify app/build.gradle like, watch out there's no = mark for my environment, maybe using gradle 4.10.3

ndk.abiFilters 'armeabi-v7a', 'arm64-v8a'

in this way, I can build the apk that passes Google 64 bit check.

However, the function supported by a specific cordova plugin, in my case, it's the cordova-plugin-weibosdk, stopped working after successfully installed on the phone.

I checked apk with Android Studio, there's no libs folder! no armeabi no arm64-v8a, no anything.

So it must be this gradle setting is not enough ? Because I can find there are libweibosdk.so file for all armeabi, arm64, x86 etc. provided in the cordova-plugin-weibosdk folder and in platforms/android/app/libs.

Then I tried copy the platforms/android/app/libs into platforms/android/app/src/main/jniLibs. As they said here.

Built again, and voila, the libs folder is inside apk.

I'm lack of Android build knowledge, so is this related to cordova-android? or I have to configure something else?

breautek commented 4 years ago

Can you remind us why you aren't using the bundle format? I need to know if there is a specific problem with the bundle format so I can address it before it gets released.

The bundle format should cover everything. A bundle format is a specific format that contains all the information required to build different variants of your APK including different:

It literally supports building thousands of different APKs. So you shouldn't have to worry about the complex build configs to support building several APKs for different architectures.

tomriddle1234 commented 4 years ago

the last comment I wrote also works for app bundle, tested yesterday. aab is better, its size is smaller, and google preferred this.

# build
ionic cordova prepare android --prod --release

# prepare app/build.gradle
# add ndk.abiFilters 'armeabi-v7a', 'arm64-v8a'

cp /home/tom/src/app/build.gradle /home/tom/src/app/platforms/android/app/

# copy libs to jniLibs
mkdir -p /home/tom/src/app/platforms/android/app/src/main/jniLibs
cp -r /home/tom/src/app/platforms/android/app/libs/* /home/tom/src/app/platforms/android/app/src/main/jniLibs/

cordova build android --release -- --packageType=bundle
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore /home/tom/src/app/release-key.keystore /home/tom/src/app/platforms/android/app/build/outputs/bundle/release/app.aab alias_name
cd /home/tom/src/app
rm app.aab
cp /home/tom/src/app/platforms/android/app/build/outputs/bundle/release/app.aab .
breautek commented 4 years ago

You shouldn't have a need to modify anything inside the platforms/ directory.

I have apps that makes use of crosswalk and I'm able to simply run cordova build android --release -- --packageType=bundle and it produces a signed bundle file (i have my sign configs stored in build.json so I don't need to use jarsigner manually). And Google happily accepts that file, states it supports both 32bit/64bit architectures, and I'm able to install the app from the google play store just fine.

Using the bundle format removes the requirement of setting abiFilters, setting proper versionCode for each APK variant, etc. If you want to build the traditional way by manually building each APK variant, then you can ping me on slack, or email me. It requires changes in the crosswalk plugin, but I can share those changes.

tomriddle1234 commented 4 years ago

I don't think current cordova-android default --packageType=bundle build configuration works in my situation. I had to add the abiFilters and copy the lib to jniLibrary otherwise it doesn't build the right aab or apk. check above.

breautek commented 4 years ago

Are you able to provide a sample repository that produces your issue so that I can take a look? It would greatly help me see exactly what you're seeing and hopefully provide a patch PR for a permanent fix. Thanks.

Guide to provide a sample repository

martinlombana commented 4 years ago

@breautek Thanks for pointing that out. Nevertheless, when I build like:

ionic cordova build android --packageType=bundle --buildConfig --xwalk64bit --release --prod It generates an apk: \platforms\android\app\build\outputs\apk\release\app-release.apk

And not an aab file. Do you have any idea on what would be wrong?

(And I do have my build.json correctly specified, I checked with the generated APK).

Thanks!

breautek commented 4 years ago

FYI, I experimented further with crosswalk over the weekend and have confirmed that this doesn't work properly with crosswalk.

I however believe this is an issue with crosswalk itself. It deploys prebuilt shared libraries, but it supplies the 32bit architecture during the build. Or it only supplies the 64bit architecture if you use the xwalk specific flag --xwalk64bit. Therefore, the shared libraries are not present during bundling. The plugin will need to be updated so that it always supplies each architecture it supports so that they can all be bundled into one AAB file.

Seeing that crosswalk is no longer maintained, obviously we are on our own if you want to use bundles with the crosswalk library.

martinlombana commented 4 years ago

If you use the trick I gave you via email, and load, locally, a modified version of the .aar, where, after opening it with winrar, you added the missing 64 lib, it works.

I am building and bundling a single aab with all the architectures. I might write a medium post soon with all the details.

But it works, 100%.

I’ll post the link here. --


Martín Lombana

TODOLOGIC.COM http://TODOLOGIC.COM | APPS & MORE

+34 633 63 02 35 | +34 946 759 137

INSTAGRAM @ https://instagram.com/todologicTODOLOGIC https://instagram.com/todologic

igorcap commented 4 years ago

@martinlombana can you tell me this trick? I'm having the same problem

martinlombana commented 4 years ago

Sorry for the delay, I was pretty busy:

I pulled together a plugin (but I didn't have time to test it as a plugin, as opposed as manually editing the files in my current testing project)

https://github.com/martinlombana/cordova-plugin-crosswalk-reloaded

You are welcome to try it, or to see inside what I changed. I don't have time till next week to document it properly and to try it.

But, in a nutshell:

  1. I inspected what the plugin downloads before each compilation. Result = the lib .aar (this is very slow by the way)
  2. I modified the .aar to include all the archs.
  3. I modified the xwalk.gradle to stop pulling the .aar from a repo and load it locally and to stop creating different flavours of apks (just one, even though the multipleapk is set to true, and I dind't modify that to make it cleaner, I will in the future).
  4. I do the usual build with cordova
  5. I go to the platforms>android and then I invoke gradlew.bat bundle
  6. I take the generated .aab file and upload that to Google Play Store.

Sorry I can't be much more specific but that should work...

I will be able to test the repo as a plugin next week and see if everything goes well.

Best!

virgolee2209 commented 4 years ago

Sorry for the delay, I was pretty busy: I pulled together a plugin (but I didn't have time to test it as a plugin, as opposed as manually editing the files in my current testing project) https://github.com/martinlombana/cordova-plugin-crosswalk-reloaded You are welcome to try it, or to see inside what I changed. I don't have time till next week to document it properly and to try it. But, in a nutshell: 0. I inspected what the plugin downloads before each compilation. Result = the lib .aar (this is very slow by the way) 1. I modified the .aar to include all the archs. 2. I modified the xwalk.gradle to stop pulling the .aar from a repo and load it locally and to stop creating different flavours of apks (just one, even though the multipleapk is set to true, and I dind't modify that to make it cleaner, I will in the future). 3. I do the usual build with cordova 4. I go to the platforms>android and then I invoke gradlew.bat bundle 5. I take the generated .aab file and upload that to Google Play Store. Sorry I can't be much more specific but that should work... I will be able to test the repo as a plugin next week and see if everything goes well. Best!

Thanks for the workaround. I now can build the APK that can be uploaded to Google play store that can work on both 32 bit and 64 bit devices. However, I still cant build the aab file like you said. When I run the command, it says successful but no output file at all. Im using quite old version of gradle. May I ask which version of gradle are you using?

breautek commented 4 years ago

Im using quite old version of gradle

cordova-android 8.10 requires minimum gradle 4.10.3 (if memory serves me right, but pretty sure it's at least 4.10).

breautek commented 4 years ago

This issue is being closed because there isn't anything cordova can do for supporting crosswalk, which has been deprecated and unmaintained since 2017.

For workaround you can try the workaround mentioned at https://github.com/apache/cordova-android/issues/805#issuecomment-529255349

matrixreal commented 4 years ago

Sorry for the delay, I was pretty busy: I pulled together a plugin (but I didn't have time to test it as a plugin, as opposed as manually editing the files in my current testing project) https://github.com/martinlombana/cordova-plugin-crosswalk-reloaded You are welcome to try it, or to see inside what I changed. I don't have time till next week to document it properly and to try it. But, in a nutshell: 0. I inspected what the plugin downloads before each compilation. Result = the lib .aar (this is very slow by the way) 1. I modified the .aar to include all the archs. 2. I modified the xwalk.gradle to stop pulling the .aar from a repo and load it locally and to stop creating different flavours of apks (just one, even though the multipleapk is set to true, and I dind't modify that to make it cleaner, I will in the future). 3. I do the usual build with cordova 4. I go to the platforms>android and then I invoke gradlew.bat bundle 5. I take the generated .aab file and upload that to Google Play Store. Sorry I can't be much more specific but that should work... I will be able to test the repo as a plugin next week and see if everything goes well. Best!

Thanks for the workaround. I now can build the APK that can be uploaded to Google play store that can work on both 32 bit and 64 bit devices. However, I still cant build the aab file like you said. When I run the command, it says successful but no output file at all. Im using quite old version of gradle. May I ask which version of gradle are you using?

Hello, what command did you use to generate apks that support both 32 & 64 bits? thanks