2012-06-01 18 views
9

La tienda de aplicaciones Google Play filtra automáticamente su aplicación a dispositivos con arquitectura de CPU compatible. P.ej. si tiene una biblioteca que solo está compilada para ARMv5, su aplicación solo aparecerá en dispositivos con procesadores ARMv5 o ARMv7.Filtrado de Android NDK y Google Play

¿Qué sucede si tengo una alternativa de Java y también quiero que mi aplicación sea descargada por dispositivos que no sean ARM? P. ej. Capté una excepción cuando intento cargar la biblioteca externa e implementar una alternativa viable en Dex bytecode (Java).

Cuando subo el apk, el desarrollador de Android consola dice: "Este apk requiere 1 plataformas nativas que serán utilizados filtrado de Google Play armeabi"

¿Es necesario para compilar las bibliotecas ficticias para x86 y MIPS? Luego, en mi código Java, verifique la arquitectura del procesador para saber si realmente puedo usar la biblioteca. Debería haber una mejor solución.

Hasta donde yo sé, no hay nada en el Manifiesto sobre la arquitectura de la CPU, y no puedo encontrar la manera en la Consola de desarrollador para apagar este filtro.

Espero que alguien que sepa mucho más que yo sobre el filtrado de Google Play y el NDK sepa la respuesta.

+0

posible idea de trabajar alrededor/burlarse: http://stackoverflow.com/questions/15146174/android-library-so-with-x86-architecture-missing-vuforia – auselen

Respuesta

11

Si bien el reventado de loadLibrary falla funcionará en cualquier dispositivo (al menos todo lo que he probado incluyendo GTV), pero Play Store no se mostrará en los dispositivos si el ABI para esa plataforma no existe en la apk.

De los documentos (http://developer.android.com/guide/appendix/market-filters.html): una aplicación que incluye bibliotecas nativas que se dirigen a una plataforma específica (ARM EABI v7 o x86, por ejemplo) solo están visibles en dispositivos compatibles con esa plataforma.

En teoría, la construcción para todas las plataformas podría apuntar a todos los dispositivos, pero en la práctica hay algunos dispositivos como Google TV que no informan ABI, lo que significa que solo los apk que no tengan código nativo aparecerán en la Play Almacenar en esos dispositivos. Sin embargo, puedes usar varios apk, 1 sin código nativo y 1 con todas las plataformas que admiten tu código nativo.

Usted puede leer acerca de la compatibilidad apk múltiples aquí: http://developer.android.com/guide/market/publishing/multiple-apks.html

+0

¿Qué pasa con lo contrario (que quiero hacer ahora)? Tengo una aplicación v7 que usa bibliotecas v5 (o algo). Esto significa que tengo bibliotecas para ambas arquitecturas a pesar de que la aplicación principal es solo para v7. Actualmente, hemos movido los archivos que no son v7 a la carpeta v7 y parece funcionar, pero es realmente feo e incorrecto. Realmente no podemos dividirlo en múltiples aplicaciones ya que ambas bibliotecas nativas son necesarias. – alaeus

+0

@alaeus Eso debería ser una pregunta separada. También está bien: Android ha mantenido el ABI compatible con versiones anteriores, por lo que el código ARMv5 funcionará perfectamente en los dispositivos ARMv6/7 (en particular, todos usan el ABI de "flotación blanda" que puede tener una importante penalización de rendimiento, pero es algo tendremos que vivir con). –

6

Hay una respuesta muy completa a esta misma pregunta aquí: http://grokbase.com/t/gg/android-ndk/125v31e6wy/play-store-market-filtering-of-ndk-libs

me deja publicar mi propia solución, es casi la misma que he publicado aquí : Android library .so with x86 architecture missing? (Vuforia)

Tiene un Android.mk normal que no puede compilar en la arquitectura x86 porque la biblioteca (libExternalLibrary.so) que está utilizando solo se proporciona para el brazo archi. Desea compilar un .so (libMyLibraryBasedOnExternalLibrary.so) basado en esta biblioteca y, por supuesto, nunca compilará en x86 sin la biblioteca.

La idea es generar librerías Dummy para x86 directamente directamente en Android.mk, usando instrucciones de compilación condicional.

1) Crear 2 archivos .cpp ficticias Dummy0.cpp y Dummy1.cpp exemple Dummy0.cpp se ve así:

#include <jni.h> 
#include <android/log.h> 
#include <stdio.h> 
#include <string.h> 
#include <assert.h> 
#include <math.h> 
#include <string> 

#ifdef __cplusplus 
extern "C" 
{ 
#endif 

int dummy0      = 0; 

#ifdef __cplusplus 
} 
#endif 

A continuación, editar el Android.mk que construye su biblioteca y modificar así:

LOCAL_PATH := $(call my-dir) 

ifeq ($(TARGET_ARCH_ABI), armeabi) 


# In this condtion block, we're compiling for arm architecture, and the libExternalLibrary.so is avaialble 
# Put every thing the original Android.mk was doing here, importing the prebuilt library, compiling the shared library, etc... 
# ... 
# ... 

else 

# In this condtion block, we're not compiling for arm architecture, and the libExternalLibrary.so is not availalble. 
# So we create a dummy library instead. 

include $(CLEAR_VARS) 
# when LOCAL_MODULE equals to ExternalLibrary, this will create a libExternalLibrary.so, which is exactly what we want to do. 
LOCAL_MODULE := ExternalLibrary 
LOCAL_SRC_FILES := Dummy0.cpp 
include $(BUILD_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
# This will create a libMyLibraryBasedOnExternalLibrary.so 
LOCAL_MODULE := MyLibraryBasedOnExternalLibrary 
# Don't forget to tell this library is based on ExternalLibrary, otherwise libExternalLibrary.so will not be copied in the libs/x86 directory 
LOCAL_SHARED_LIBRARIES := ExternalLibrary 
LOCAL_SRC_FILES := Dummy1.cpp 
include $(BUILD_SHARED_LIBRARY) 

endif 

Por supuesto, asegúrese de que en el código que nunca se llama a la biblioteca cuando la aplicación se ejecuta en un x86 único dispositivo:

if ((android.os.Build.CPU_ABI.equalsIgnoreCase("armeabi")) || (android.os.Build.CPU_ABI2.equalsIgnoreCase("armeabi"))) { 
    // Good I can launch 
    // Note that CPU_ABI2 is api level 8 (v2.2) 
    // ... 
} 
+0

Recibo el siguiente error cuando intento pasos similares: /android/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/../lib/gcc/arm-linux-androideabi/ 4.6.x-google /../../../../ arm-linux-androideabi/bin/ld: error: no se puede encontrar -lExternalLibrary.so collect2: ld devuelto 1 estado de salida –

+0

Es un error de compilación de qué arquitectura? ¿Puedes ver en los registros la compilación de Dummy0.cpp? – jptsetung

+0

Estoy construyendo para la arquitectura Arm, pero primero lib ExternalLibrary.so se genera. No sé por qué viene a la parte else cuando estoy construyendo en arm-architecture. ¿Usaré el enfoque Ndk en lugar de esto? –