android maquina - ¿Cómo resolver el problema con la limitación del compilador Dalvik en los métodos de 64K?




funcionamiento ejecucion (7)

Mi equipo y yo hemos heredado un gran proyecto de Android de otro equipo. Se informa que toda la aplicación con todas las bibliotecas incluidas tiene alrededor de 35000 métodos. Ahora tenemos la tarea de implementar un nuevo servicio en la aplicación donde necesitamos usar Protocol Buffers.

El problema es que el archivo .jar generado con todos los archivos .proto necesarios crea otro par de 35000 métodos, que son 70000 métodos. Y si no lo sabe, el compilador de Android tiene una limitación de 65536 métodos por archivo .dex. Claramente hemos superado ese límite y estamos obteniendo el siguiente error al intentar compilar la aplicación:

Unable to execute dex: method ID not in [0, 0xffff]: 65536
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

Sí, la arquitectura de la aplicación probablemente debería ser reestructurada, pero eso llevará tiempo. Y por ahora estamos tratando de encontrar una solución para solucionar este problema temporalmente.

¿Alguna sugerencia?


Answers

Si está utilizando eclipse, este es el trabajo más fácil que se puede hacer alrededor de ¡ Haga clic aquí!


En las versiones de los servicios de Google Play anteriores a 6.5, tenía que compilar todo el paquete de API en su aplicación. En algunos casos, hacerlo hizo más difícil mantener el número de métodos en su aplicación (incluidas las API de marco, los métodos de biblioteca y su propio código) bajo el límite de 65,536.

Desde la versión 6.5, en su lugar, puede compilar selectivamente las API del servicio Google Play en su aplicación. Por ejemplo, para incluir solo las API de Google Fit y Android Wear, reemplace la siguiente línea en su archivo build.gradle:

compile 'com.google.android.gms:play-services:6.5.87'

con estas lineas:

compile 'com.google.android.gms:play-services-fitness:6.5.87'
compile 'com.google.android.gms:play-services-wearable:6.5.87'

Para más referencia, puede hacer clic here


Si este es el primer uso de los búferes de protocolo, puede buscar implementaciones JavaME alternativas, es decir

Hay otros listados en complementos de terceros . Si no ha usado ninguno de ellos, pero parecen ser más pequeños y no tienen todos los métodos creados por los búferes de protocolo estándar.


Recientemente hemos agregado Nano Protobufs a Android, lo que reduce significativamente la cantidad de métodos generados.




Déjame agregar mis dos centavos a la discusión. Como se señaló en otras respuestas, la codificación en zig-zag puede pensarse como un giro de magnitud de signo. Este hecho se puede utilizar para implementar funciones de conversión que funcionan con enteros de tamaño arbitrario. Por ejemplo, uso el siguiente código en uno de mis proyectos de Python:

def zigzag(x: int) -> int:
    return x << 1 if x >= 0 else (-x - 1) << 1 | 1

def zagzig(x: int) -> int:
    assert x >= 0
    sign = x & 1
    return -(x >> 1) - 1 if sign else x >> 1

Estas funciones funcionan a pesar de que el int de Python no tiene un ancho de bits fijo; en cambio, se extiende dinámicamente. Sin embargo, este enfoque puede ser ineficiente en los lenguajes compilados, ya que requiere ramificación condicional.





android protocol-buffers dalvik dex