web-dev-qa-db-fra.com

Comment réduire la taille de l'apk d'une application Android nécessitant openCv lib (uniquement pour le traitement d'images)

Je construis une application Android avec min SDK 15, qui utilise la bibliothèque OpenCV.Le problème est lorsque je construis apk taille de plus de 60 MB qui n'est pas très grande. 

J'ai vérifié le fichier de l'application, j'ai constaté que la taille était trop grande en raison du fichier libopencv_Java3.so dans toutes les architectures telles que amr64, armeabi, mips, x86, etc. 

 enter image description here

J'utilise opneCv uniquement pour le traitement d'images. Cette bibliothèque possède de nombreuses fonctionnalités telles que le traitement vidéo, les images 3D, la détection d'objets, etc., dont je n'ai pas besoin dans mon application, comme 

Si je supprime tous ces fichiers et que je construis APK, la taille sera alors réduite de 50 Mo. Mais pour que cette application fonctionne, je dois installer OpenCVManager pour exécuter mon application. 

Existe-t-il un moyen de réduire la taille de mon apk?

Ou est-il possible d'extraire uniquement la fonctionnalité de OpenCV qui m'intéresse et de créer .so pour ces fonctionnalités?

10
Shakeeb Ayaz

Pour moi, alijandro answer 2nd réponse était la meilleure solution mais je me suis retrouvé coincé dans le processus. Donc, j'ai résolu le problème en divisant apk. Vous devez télécharger des apk liés à la plate-forme et également un apk universel.Il serait idéal, car OpenCV ne fournit pas de dépendance supplémentaire au niveau du module.

Universal apk sera téléchargé dans le cas où la plate-forme ne correspond pas. Ici est un blog joliment écrit sur apk publishing mutiple apk. Vous devez conserver le même identifiant d'application, le magasin de clés, la même version d'application mais une version de code différente

Étape 1 . Ajouter le code de gradation pour la division spk. Incluez l'architecture pour laquelle vous souhaitez créer un apk séparé.

Android{
//......
splits {
    abi {
        enable true
        reset()
        include "armeabi","armeabi-v7a",'arm64-v8a',"mips","x86","x86_64",'arm64-v8a'
        universalApk true
    }
}
}

Étape 2 . Ajoutez le code ci-dessous pour une version de code différente pour une plate-forme différente.

Android{
//......
}
ext.versionCodes = ['armeabi': 3, 'armeabi-v7a': 4, 'arm64-v8a': 5, 
mips: 6, 'x86': 7, 'x86_64': 8]
import com.Android.build.OutputFile
// For each APK output variant, override versionCode with a combination 
// of ABI APK value * 1000 + defaultConfig.versionCode
Android.applicationVariants.all { variant ->
// assign different version code for each output
variant.outputs.each { output ->
    def abiFilter = output.getFilter(OutputFile.ABI)
    def abiMultiplier = 0
    if (abiFilter != null) {
        abiMultiplier = project.ext.versionCodes.get(abiFilter)
    }
    output.versionCodeOverride =
            abiMultiplier * 1000 + Android.defaultConfig.versionCode
   }
  }

Par exemple, si le code de version initial était 1, les codes générés seront:

 armeabi -> 3001
 armeabi-v7a -> 4001
 arm64-v8a -> 5001
 mips -> 6001
 x86 -> 7001
 x86_64 -> 8001

Tous ensemble, votre code Gradle ressemblera à ceci.

 Android{
//......
splits {
abi {
    enable true
    reset()
    include "armeabi","armeabi-v7a",'arm64-
v8a',"mips","x86","x86_64",'arm64-v8a'
    universalApk true
 }
 }

 ext.versionCodes = ['armeabi': 3, 'armeabi-v7a': 4, 'arm64-v8a': 5, 
mips: 6, 'x86': 7, 'x86_64': 8]
import com.Android.build.OutputFile
Android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def abiFilter = output.getFilter(OutputFile.ABI)
def abiMultiplier = 0
if (abiFilter != null) {
    abiMultiplier = project.ext.versionCodes.get(abiFilter)
}
output.versionCodeOverride =
        abiMultiplier * 1000 + Android.defaultConfig.versionCode
}
}

Maintenant, vous devez publier tous les apk sur Playstore un par un. 

Note : Lors de la publication, assurez-vous de conserver toute la plate-forme et l'apk universel.

6
Shakeeb Ayaz

Vous ne pouvez pas supprimer la bibliothèque libopencv_Java3.so, c'est obligatoire.

Existe-t-il un moyen de réduire la taille de mon apk?

Sans modifier la bibliothèque libopencv_Java3.so, vous pouvez créer plusieurs apks pour différentes architectures plutôt que de créer un fichier APK à plat. Une seule arche de libopencv_Java3.so sera intégrée à votre fichier APK scindé. Par exemple, vous pouvez utiliser la configuration ci-dessous pour générer uniquement les architectures x86, armeabi-v7a et mips dans votre build.gradle.

splits {
    abi {
      enable true
      reset()
      include "x86", "armeabi-v7a", "mips"
      universalApk false
    }
  }

Plus d'informations sur la réduction de la taille d'apk par fractionnement, voir ici .

Ou est-il possible d'extraire uniquement la fonctionnalité d'OpenCV qui m'intéresse et de créer .so pour ces fonctionnalités?

Oui bien sûr. Le processus de création de opencv est entièrement personnalisé. Si vous savez déjà comment créer opencv pour Android, allez directement à étape 2 .

étape 1

  1. obtenir la source de opencv
  2. créer un répertoire opencv_build
  3. passez au répertoire racine de opencv que vous venez de cloner
  4. invoquer le script de construction platforms/Android/build_sdk.py --ndk_path $Android_NDK_ROOT --sdk_path $Android_SDK_ROOT ../opencv_build .

Remarque

La procédure de construction nécessite la commande Android pour construire apk. La version de l'outil de SDK Android doit donc être inférieure à 25.3.0; à partir de 25.3.0, la commande Android a été supprimée.

étape 2

Supposons que étape 1 ci-dessus fonctionne correctement. Ici, je prends armeabi-v7a comme exemple.

  1. Allez dans le répertoire opencv_build/o4a/lib/armeabi-v7a
  2. Vous trouverez de nombreux * .a pour différents modules opencv, la bibliothèque libopencv_Java3.so également dans ce répertoire
  3. Créez une petite bibliothèque de partage de version à partir du module dont vous avez besoin, par exemple

    $ arm-linux-androideabi-gcc -shared -o libopencv_tiny.so --sysroot=$Android_NDK_ROOT/platforms/Android-9/Arch-arm -Wl,--whole-archive libopencv_core.a libopencv_imgcodecs.a libopencv_imgproc.a -Wl,--no-whole-archive
    $ du -h libopencv_tiny.so 
    5.2M    libopencv_tiny.so
    $ arm-linux-androideabi-strip --strip-unneeded libopencv_tiny.so 
    $ du -h libopencv_tiny.so 
    4.1M    libopencv_tiny.so
    $ du -h libopencv_Java3.so 
    9.8M    libopencv_Java3.so
    

La version minuscule qui comprend core, image codecs et image proc a une taille 4.1M après strip, mais la version complète libopencv_Java3.so a une taille de 9.8M.

J'utilise libopencv_tiny.so comme nom juste pour des raisons pratiques, vous devez utiliser le même nom libopencv_Java3.so dans votre projet. Sinon, System.loadLibrary en Java ne peut pas trouver la bibliothèque native.

Pour le reste de l'architecture dont vous avez besoin, par exemple arm64-v8a, procédez de la même manière.

7
alijandro

Les deux réponses ci-dessus sont assez complètes, mais juste au cas où vous auriez besoin de plus de détails et de boutons de réglage, trouvez ceci article

0
Milind Deore

S'il contient plus de ressources, utilisez le code ci-dessous dans votre fichier Gradle. Il supprime les ressources inutilisées du projet.

 buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
        }
    }

Si vous souhaitez supprimer le code inutilisé, utilisezMéthodes 64K

LINK2

Vous pouvez également poser une question dans OpenCV 

site Q/A

0
Arpit Patel