Выпуск подписанного apk Reaction-native (0.59.9), который не падает на устройствах с Android версии 5.1.1, а на устройствах версий 6 и 7 - PullRequest
0 голосов
/ 09 июля 2019

Я создал проект, используя реактивную версию 0.59.9 с минимальной версией SDK 16, целевую версию SDK 28. Когда я генерирую apk отладки, он отлично работает на устройстве, но я сгенерировал релиз apk, используя android studio с файлом jks.Он устанавливается, но не запускается при запуске приложения на vivo y21ll (версия 5.1.1), но устанавливается и работает нормально на Redmi note 5 (версия 6).Мой android / app / build.gradle файл:

apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services' // <--- this should be 
the last line

import com.android.build.OutputFile

/** * The react.gradle file registers a task for each build variant 
(e.g. bundleDebugJsAndAssets
 * and bundleReleaseJsAndAssets).
 * These basically call `react-native bundle` with the correct 
  arguments during the Android build
 * cycle. By default, bundleDebugJsAndAssets is skipped, as in 
 debug/dev mode we prefer to load the
 * bundle directly from the development server. Below you can see all 
 the possible configurations
 * and their defaults. If you decide to add a configuration block, make 
 sure to add it before the
 * `apply from: "../../node_modules/react-native/react.gradle"` line.
 *
 * 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,
 *
 *   // whether to bundle JS and assets in another build variant (if 
 configured).
 *   // See http://tools.android.com/tech-docs/new-build-system/user- 
 guide#TOC-Build-Variants
 *   // The configuration property can be in the following formats
 *   //         'bundleIn${productFlavor}${buildType}'
 *   //         'bundleIn${buildType}'
 *   // bundleInFreeDebug: true,
 *   // bundleInPaidRelease: true,
 *   // bundleInBeta: true,
 *
 *   // whether to disable dev mode in custom build variants (by 
 default only disabled in release)
 *   // for example: to disable dev mode in the staging build type (if 
 configured)
 *   devDisabledInStaging: true,
 *   // The configuration property can be in the following formats
 *   //         'devDisabledIn${productFlavor}${buildType}'
 *   //         'devDisabledIn${buildType}'
 *
 *   // 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/**"],
 *
 *   // override which node gets called and with what additional 
 arguments
 *   nodeExecutableAndArgs: ["node"],
 *
 *   // supply additional arguments to the packager
 *   extraPackagerArgs: []
 * ]
  */

 project.ext.react = [
    entryFile: "index.js"
  ]

  apply from: "../../node_modules/react-native/react.gradle"

 /**
  * Set this to true to create two separate APKs instead of one:
  *   - An APK that only works on ARM devices
  *   - An APK that only works on x86 devices
  * The advantage is the size of the APK is reduced by about 4MB.
  * Upload all the APKs to the Play Store and people will download
  * the correct one based on the CPU architecture of their device.
  */
  def enableSeparateBuildPerCPUArchitecture = false

  /**
  * Run Proguard to shrink the Java bytecode in release builds.
  */
  def enableProguardInReleaseBuilds = true

  android {
     compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
     }

defaultConfig {
    applicationId "com.tapontech.wrapoconnect"
    minSdkVersion rootProject.ext.minSdkVersion
    targetSdkVersion rootProject.ext.targetSdkVersion
    versionCode 1
    versionName "1.0"
}
splits {
    abi {
        reset()
        enable enableSeparateBuildPerCPUArchitecture
        universalApk false  // If true, also generate a universal APK
        include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
    }
}
buildTypes {
    release {
        minifyEnabled enableProguardInReleaseBuilds
        proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
    }
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
    variant.outputs.each { output ->
        // For each separate APK per architecture, set a unique version 
 code as described here:
        // http://tools.android.com/tech-docs/new-build-system/user- 
  guide/apk-splits
        def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3, 
   "x86_64": 4]
        def abi = output.getFilter(OutputFile.ABI)
        if (abi != null) {  // null for the universal-debug, universal- 
   release variants
            output.versionCodeOverride =
                    versionCodes.get(abi) * 1048576 + 
 defaultConfig.versionCode
           }
        }
     }
  }

 dependencies {
    implementation project(':react-native-google-signin')
    implementation project(':react-native-fbsdk')
    implementation project(':react-native-firebase')
    implementation project(':react-native-view-pdf')
    implementation project(':react-native-vector-icons')
    implementation project(':react-native-orientation')
   implementation "com.google.android.gms:play-services-base:16.1.0"
   implementation "com.google.firebase:firebase-core:16.0.9"
   implementation "com.google.firebase:firebase-messaging:18.0.0"

   implementation 'me.leolin:ShortcutBadger:1.1.21@aar'
    implementation 'com.facebook.android:facebook-android-sdk:4.22.0'
     implementation project(':react-native-device-info')
    implementation project(':react-native-cookies')
   implementation fileTree(dir: "libs", include: ["*.jar"])
   implementation "com.android.support:appcompat- 
  v7:${rootProject.ext.supportLibVersion}"
    implementation "com.facebook.react:react-native:+"  // From 
     node_modules
   }

 // Run this once to be able to run the application with BUCK
 // puts all compile dependencies into folder libs for BUCK to use
 task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
  }

my android / build.gradle is:

 // Top-level build file where you can add configuration options 
  common to all sub-projects/modules.

buildscript {
   ext {
    buildToolsVersion = "28.0.3"
    minSdkVersion = 16
    compileSdkVersion = 28
    targetSdkVersion = 28
    supportLibVersion = "28.0.0"
    }
  repositories {
    google()
    jcenter()
   }
  dependencies {
    classpath('com.android.tools.build:gradle:3.4.0')
    classpath 'com.google.gms:google-services:4.2.0'

    // NOTE: Do not place your application dependencies here; they 
        belong
    // in the individual module build.gradle files
    }
   }

   allprojects {
     repositories {
        mavenLocal()
        google()
       jcenter()
        maven {
        // All of React Native (JS, Obj-C sources, Android binaries) is 
         installed from npm
        url "$rootDir/../node_modules/react-native/android"
       }
     }
   }

my android / gradle / gradle-wrapper.properties :

   distributionBase=GRADLE_USER_HOME
   distributionPath=wrapper/dists
   distributionUrl=https\://services.gradle.org/distributions/gradle- 
   5.4.1-all.zip
   zipStoreBase=GRADLE_USER_HOME
   zipStorePath=wrapper/dists

my package.json Файл:

    {
    "name": "Wrapo",
    "version": "0.0.1",
    "private": true,
   "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
   },
 "dependencies": {
    "firebase": "^5.0.3",
    "moment": "^2.24.0",
    "react": "16.8.3",
    "react-native": "0.59.9",
    "react-native-check-box": "^2.1.7",
    "react-native-cookies": "^3.3.0",
    "react-native-device-info": "^2.2.1",
    "react-native-elements": "^0.19.1",
    "react-native-extended-stylesheet": "^0.11.2",
    "react-native-fbsdk": "^0.8.0",
    "react-native-firebase": "^5.5.4",
    "react-native-flash-message": "^0.1.13",
    "react-native-gesture-handler": "^1.3.0",
    "react-native-gifted-chat": "^0.9.11",
    "react-native-google-signin": "^2.0.0",
    "react-native-iphone-x-helper": "^1.2.1",
    "react-native-keyboard-aware-scroll-view": "^0.8.0",
    "react-native-linkedin": "^1.3.2",
    "react-native-material-dropdown": "^0.11.1",
    "react-native-options-menu": "^2.0.2",
    "react-native-orientation": "^3.1.3",
    "react-native-status-bar-height": "^2.3.1",
    "react-native-tab-view": "^1.2.0",
    "react-native-vector-icons": "^6.6.0",
    "react-native-view-more-text": "^2.1.0",
    "react-native-view-pdf": "^0.8.6",
    "react-navigation": "^3.11.0",
    "react-redux": "^7.1.0",
    "redux": "^4.0.1",
    "redux-logger": "^3.0.6",
    "redux-persist": "^5.10.0",
    "redux-thunk": "^2.3.0",
    "striptags": "^3.1.1",
    "uuid": "^3.3.2",
    "whatwg-fetch": "^3.0.0"
   },
"devDependencies": {
   "@babel/core": "7.5.0",
   "@babel/runtime": "7.5.0",
    "babel-jest": "24.8.0",
    "jest": "24.8.0",
   "metro-react-native-babel-preset": "0.55.0",
   "react-test-renderer": "16.8.3"
  },
  "jest": {
     "preset": "react-native"
    }
  }

Пожалуйста, получитемне некоторые подсказки, где я ошибся или какие еще дополнительные шаги я могу сделать .. чтобы это работало на всех устройствах.

1 Ответ

0 голосов
/ 23 июля 2019

Это потому, что вы включили "enableProguardInReleaseBuilds" в файле на уровне приложения build.gradle .Включив это, вы даете команду программе gradle запустить proguard для сжатия байт-кода Java в сборках релизов, что обеспечивает небольшой размер APK-релизов.

Для решения этой проблемы у нас есть два подхода:

Сначала необходимо отключить enableProguardInReleaseBuilds в вашем build.gradle уровня приложения файл

    def enableProguardInReleaseBuilds = false

Вы используете act-native-fbsdk , который вызывает сбойв релизе сборки.В процессе аутентификации Facebook Fbsdk получает доступ к собственному веб-представлению для аутентификации Facebook.Когда enableProguardInReleaseBuilds включен, он сжимает байт-код Java Fbsdk также, из-за чего мы не можем получить доступ к собственному веб-представлению, и это приводит к сбою.Поэтому, если вы не хотите отключать enableProguardInReleaseBuilds и ваш приоритет - меньший размер APK, вам не нужно ничего менять в файле build.gradle уровня приложения, просто оставьте его как есть:

    def enableProguardInReleaseBuilds = true

и добавьтеследующий фрагмент кода в файле proguard-rules.pro , присутствующий в папке приложения для Android

    -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
    -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
    -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip

    # Do not strip any method/class that is annotated with @DoNotStrip
    -keep @com.facebook.proguard.annotations.DoNotStrip class *
    -keep @com.facebook.common.internal.DoNotStrip class *
    -keepclassmembers class * {
        @com.facebook.proguard.annotations.DoNotStrip *;
        @com.facebook.common.internal.DoNotStrip *;
    }

    -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
      void set*(***);
      *** get*();
    }

    -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
    -keep class * extends com.facebook.react.bridge.NativeModule { *; }
    -keepclassmembers,includedescriptorclasses class * { native <methods>; }
    -keepclassmembers class *  { @com.facebook.react.uimanager.UIProp <fields>; }
    -keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
    -keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }

    -dontwarn com.facebook.react.**

    # okhttp

    -keepattributes Signature
    -keepattributes *Annotation*
    -keep class okhttp3.** { *; }
    -keep interface okhttp3.** { *; }
    -dontwarn okhttp3.**

    # okio

    -keep class sun.misc.Unsafe { *; }
    -dontwarn java.nio.file.*
    -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
    -dontwarn okio.**

    -keepclassmembers class * {
        @android.webkit.JavascriptInterface <methods>;
    }

    -keepattributes JavascriptInterface
    -keepattributes *Annotation*

    -dontwarn com.facebook.**
    -keep class com.facebook.** {*;}

    -optimizations !method/inlining/*

    -ignorewarnings
    -keep class * {
        public private *;
    } 

Хотя вы можете создавать отдельные APK для разных архитектур ЦП, которые могут еще больше уменьшить ваш размердо 1/3 текущей версии, включив enableSeparateBuildPerCPUArchitecture в вашем уровне приложения build.gradle файл

    def enableSeparateBuildPerCPUArchitecture = true

Я столкнулся с похожими проблемами при интеграции аутентификации Facebook,Платежный шлюз Razorpay и все те SDK, которые получают доступ к нативным веб-представлениям через реагирующий нативный мост и решают их аналогичным образом, как указано выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...