Si las aplicaciones de Android están escritas en Java, ¿por qué no puedes simplemente copiar el archivo JAR en el dispositivo y ejecutarlo?

Tienes razón cuando supones que las aplicaciones Android están escritas en lenguaje Java, pero incluso eso no es una afirmación completa, porque consta de un par de partes más.

Entonces, en el escritorio va así:

  1. Escribes código Java. Cosas estándar, escribes un método principal (o más), seleccionas la clase principal, eliges la versión, tienes todas las librerías estándar a tu disposición, etc.
  2. Lo construyes usando Ant, Maven o Gradle (sólo por nombrar los más populares) y lo empaquetas en .jar que contiene un manifiesto (metadatos) y archivos .class, opcionalmente con algunos otros recursos
  3. Distribuyes el archivo .jar que acabas de construir a otros
  4. Los otros descargan ese archivo, y lo lanzan usando la máquina virtual Java. Si la versión de la JVM es inferior a la del código para el que lo has escrito (¿recuerdas el primer paso?), simplemente mostrará un error

Android, por otro lado, es un poco más complejo:

  1. Escribe el código Java.
    1. Esta vez no tienes un método main, sino Actividades. Cada actividad tiene un ciclo de vida definido y métodos de devolución de llamada que puede utilizar (por ejemplo, onCreate, onStart, onResume, onPause, onStop, onDestroy, y así sucesivamente). Usted no define el fallo del programa, sino que el sistema decide cuándo se llama a cada uno y usted tiene la oportunidad de hacer lo que quiera en un momento determinado.
    2. Así que, siguiendo la misma lógica de arriba, usted necesita declarar una actividad principal, y lo hace en un archivo llamado AndroidManifest.xml (es el que se lanza primero). También es necesario declarar todas las demás actividades, servicios, receptores de difusión, permisos, características de hardware, etc. que planea utilizar en el mismo archivo, por lo que el sistema sabe que existen y / o son necesarios, por lo que Play Store puede filtrar a cabo para los dispositivos que no son compatibles.
    3. Usted don't elegir una versión, en lugar de elegir el nivel mínimo de SDK, que es la versión mínima de Android que planea construir para y colocarlo en el manifiesto. Hasta KitKat, la máquina virtual (Dalvik) sabía ejecutar el bytecode de Java 6, y en KitKat y versiones posteriores, también puede ejecutar Java 7 (Dalvik/ART). No sé a ciencia cierta si es el mismo bytecode que en los ordenadores, pero es bastante similar. Además, fíjate en que he utilizado la palabra bytecode: incluso cuando se desarrollaba para dispositivos anteriores a KitKat, se podían utilizar características como el operador diamante, que es básicamente azúcar sintáctico. Si intentas ejecutar código Java 7 en dispositivos pre-KitKat, tu aplicación se bloqueará (Android Studio también se quejará si detecta que intentas hacer tal cosa).
    4. No puedes usar todas las librerías, por ejemplo, Swing. NIO también está ausente. JavaFX es posible, pero no está en la biblioteca estándar, sino que es un puerto. Se espera que utilices XML cuando definas los diseños y luego obtengas mediante programación los objetos Java apropiados para los que pretendas establecer escuchas o cambiar más tarde. La actividad puede acceder a la vista raíz, y como XML es jerárquico es todo lo que se necesita. Es responsable no sólo del código Java, sino también de los recursos XML, que incluyen diseños, cadenas, colores, enteros, etc. que se definen en archivos XML separados y se utilizan en toda la aplicación. No construye un archivo .jar, sino un .apk, que en esencia es un .zip como el .jar, pero que contiene un archivo llamado classes.dex que contiene archivos .class, además del Manifest y los recursos en carpetas separadas (por defecto comprimidos en un formato denominado "XML binario"), además de (opcionalmente) los activos. Manifiesto debe permanecer legible para terceros.
    5. La distribución difiere porque hay un mercado central - Play Store.
      1. Comprueba el manifiesto de su aplicación, extrae los datos necesarios (nombre, autor, cosas que requiere del dispositivo en el que se va a instalar) y lo muestra al usuario final en consecuencia. Así, si el usuario utiliza, por ejemplo, Android 4.0 y en el manifiesto se requiere Android 4.1, su aplicación no aparecerá en los resultados de búsqueda para ese usuario, y lo mismo ocurre con las características de hardware como el GPS. Si un usuario sigue un enlace directo, sólo recibirá un mensaje de "dispositivo no compatible".
      2. También puedes distribuir a otros mercados, que pueden tener sus propias políticas, o poner un archivo .apk para su descarga. El inconveniente es que en Android, la instalación de aplicaciones desde fuentes de terceros está desactivada por defecto, por lo que antes de instalar un .apk el usuario tendría que activar esa opción en los ajustes. Esto se hace porque Google no puede controlar, ni responder, por aplicaciones posiblemente maliciosas fuera de la Play Store, o asegurar la calidad y compatibilidad apropiadas.
    6. Así que, cuando la aplicación se instala (es decir, se copia en la carpeta /data/app/, se crean las carpetas apropiadas /data/data/ y similares y se registran en el gestor de paquetes del sistema), es finalmente el momento de lanzarla. No hay una aplicación separada de la "Máquina Virtual Java" como en los ordenadores, sino que todo el trabajo pesado lo hace la máquina por defecto del sistema (Dalvik o ART). No hay una interfaz nativa en el sentido habitual de la palabra, sino que el NDK expone algunas API adicionales, normalmente peligrosas, y las cosas relacionadas con el sistema las realiza el Libcore, que también está integrado en el sistema.
      Debido a que está algo disperso, no se puede simplemente "actualizar Java" para un determinado dispositivo, sino que hay que realizar una actualización de todo el sistema operativo. Todos los fabricantes de teléfonos añaden marcas, interfaces de usuario y bloatware específicos de la empresa y, cuando ya no tiene sentido desde el punto de vista financiero seguir desarrollando para el dispositivo, simplemente dejan de enviar actualizaciones a determinados modelos de dispositivos. Ahora nos encontramos con la situación de que, aunque se espera que Android N traiga el último y mejor OpenJDK, nos quedaremos atascados en Java 6 durante un tiempo, y luego quizá podamos "actualizar" a 7. No mucha gente sentirá el cambio de versión por lo menos hasta dentro de unos años (como referencia, hay un 25% de dispositivos pre-KitKat en el mercado a partir del 2 de mayo, y sólo el 7,5% están usando la última versión, Marshmallow)

Así que no es realmente posible usar JAR en Android, porque la única cosa común que Java en Windows/Linux/OSX tiene con Java en Android es la especificación del lenguaje, y eso'es sólo una parte de la ecuación. .apk contiene un poco más de datos, se ejecuta un poco diferente, y las responsabilidades que tiene JVM en los ordenadores están dispersos en Android.