发布签名的apk的react-native(0.59.9)不会在版本5.1.1的android设备上崩溃,但是在版本6和7的设备上崩溃

时间:2019-07-09 05:51:49

标签: macos android-studio

我使用react-native版本0.59.9创建了一个项目,最低sdk版本为16,目标sdk版本为28。当我生成调试apk时,它在设备上运行良好,但是我使用android studio和jks文件生成了发布apk。它已安装但在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'
  }

我的 android / build.gradle 是:

 // 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"
       }
     }
   }

我的 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

我的 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 :(得分:0)

这是因为您已经应用程序级build.gradle 文件中启用了“ enableProguardInReleaseBuilds” 。通过启用此功能,您将指示gradle运行proguard来缩小发行版本中的Java字节代码,以确保发行APK的尺寸较小。

要解决此问题,我们有两种方法:

首先是在应用程序级build.gradle 文件中禁用enableProguardInReleaseBuilds

    def enableProguardInReleaseBuilds = false

您正在使用 react-native-fbsdk ,这会导致发行版本崩溃。在Facebook身份验证过程中,Fbsdk访问用于Facebook身份验证的本机Webview。启用enableProguardInReleaseBuilds后,它也会缩小Fbsdk Java字节码,因此我们也无法访问本地Web视图,从而导致崩溃。因此,如果您不想禁用enableProguardInReleaseBuilds并且您的优先级是较小的APK大小,则无需更改应用程序级build.gradle文件中的任何内容,只需将其保持不变即可:

    def enableProguardInReleaseBuilds = true

,然后将以下代码段添加到android应用文件夹中的 proguard-rules.pro 文件中

    -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 *;
    } 

尽管您可以为不同的CPU体系结构构建单独的APK,通过在 app级build.gradle中启用 enableSeparateBuildPerCPUArchitecture ,可以将大小进一步减小到当前版本的1/3 strong>文件

    def enableSeparateBuildPerCPUArchitecture = true

在集成Facebook身份验证,Razorpay支付网关以及所有所有通过react-native桥访问本机Webview并以上述类似方式解决它们的SDK时,我遇到了类似的问题。