Actividad de Android ClassNotFoundException: probé todo
Acabo de refactorizar una aplicación en una biblioteca de marco y una aplicación, pero ahora, cuando intento iniciar la aplicación en el emulador, aparece el siguiente seguimiento de la pila de errores:
06-02 18:22:35.529: E/AndroidRuntime(586): FATAL EXCEPTION: main
06-02 18:22:35.529: E/AndroidRuntime(586): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.matthewrathbone.eastersays/com.matthewrathbone.eastersays.EasterSimonSaysActivity}: java.lang.ClassNotFoundException: com.matthewrathbone.eastersays.EasterSimonSaysActivity in loader dalvik.system.PathClassLoader[/data/app/com.matthewrathbone.eastersays-1.apk]
06-02 18:22:35.529: E/AndroidRuntime(586): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
06-02 18:22:35.529: E/AndroidRuntime(586): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
06-02 18:22:35.529: E/AndroidRuntime(586): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
06-02 18:22:35.529: E/AndroidRuntime(586): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
06-02 18:22:35.529: E/AndroidRuntime(586): at android.os.Handler.dispatchMessage(Handler.java:99)
06-02 18:22:35.529: E/AndroidRuntime(586): at android.os.Looper.loop(Looper.java:123)
06-02 18:22:35.529: E/AndroidRuntime(586): at android.app.ActivityThread.main(ActivityThread.java:4627)
06-02 18:22:35.529: E/AndroidRuntime(586): at java.lang.reflect.Method.invokeNative(Native Method)
06-02 18:22:35.529: E/AndroidRuntime(586): at java.lang.reflect.Method.invoke(Method.java:521)
06-02 18:22:35.529: E/AndroidRuntime(586): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-02 18:22:35.529: E/AndroidRuntime(586): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
06-02 18:22:35.529: E/AndroidRuntime(586): at dalvik.system.NativeStart.main(Native Method)
06-02 18:22:35.529: E/AndroidRuntime(586): Caused by: java.lang.ClassNotFoundException: com.matthewrathbone.eastersays.EasterSimonSaysActivity in loader dalvik.system.PathClassLoader[/data/app/com.matthewrathbone.eastersays-1.apk]
06-02 18:22:35.529: E/AndroidRuntime(586): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
06-02 18:22:35.529: E/AndroidRuntime(586): at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
06-02 18:22:35.529: E/AndroidRuntime(586): at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
06-02 18:22:35.529: E/AndroidRuntime(586): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
06-02 18:22:35.529: E/AndroidRuntime(586): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)
06-02 18:22:35.529: E/AndroidRuntime(586): ... 11 more
Por lo general, esto significa que el archivo de manifiesto está incorrecto de alguna manera, pero he verificado todo lo que se me ocurre.
Aquí está mi clase de actividad:
package com.matthewrathbone.eastersays;
import android.os.Bundle;
import com.rathboma.simonsays.Assets.Season;
import com.rathboma.simonsays.SeasonPicker;
import com.rathboma.simonsays.SimonSaysActivity;
public class EasterSimonSaysActivity extends SimonSaysActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
public SeasonPicker getSeasonPicker() {
return new SeasonPicker(){
@Override
public Season getSeason() {
// TODO Auto-generated method stub
return Season.EASTER;
}
};
}
}
Como puede ver, aparece correctamente en el manifiesto:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.matthewrathbone.eastersays"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".EasterSimonSaysActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
No tengo idea de cómo solucionar este problema y agradecería cualquier ayuda. He analizado muchas preguntas similares en SO sin ver este comportamiento en particular.
Más información:
- Revisé el interior del APK generado y la clase tiene una entrada en el archivo Classes.dex.
- Intenté limpiar/construir el proyecto en eclipse.
- Intenté usar una imagen de dispositivo totalmente nueva que aún no tiene una copia del APK.
- Cambié el proyecto de la biblioteca a un Java normal y luego volví a cambiar a un proyecto de Android, no hay diferencia.
- Agregar el resumen SimonSaysActivity al manifiesto no hace ninguna diferencia.
- Intenté hacer de cada dependencia un proyecto de biblioteca de Android y sincronizar la versión de Android que requieren, pero no ayudó.
Encontré la solución (ver más abajo). A todos los que publicaron una respuesta/comentario: ¡Todos ustedes son geniales, gracias por ayudarme a resolver los problemas!
Parece que esto se debe a una actualización de las herramientas del SDK. Gracias a @Nick a continuación en los comentarios de este enlace: http://iqadd.com/item/noclassdeffounderror-adt-fix
Pasé algún tiempo jugando con mi propio proyecto y puedo replicar su problema y obtener exactamente el mismo seguimiento de la pila de excepción cuando intento ejecutar mi proyecto principal, así que creo que esta podría ser la causa:
Tal como pensé, se trata de cómo haces referencia a tu proyecto de biblioteca de Android en el proyecto principal de Android, una configuración simple de Eclipse.
La forma incorrecta:
haga clic con el botón derecho en el proyecto principal, elija Properties -> Java Build Path -> Projects -> Add...
, esto agrega el proyecto de biblioteca de Android como un proyecto de dependencia en la ruta de compilación del proyecto principal de Android; esto no funciona. Si todos los recursos necesarios relacionados con Android están definidos en el proyecto principal, no obtendrá ningún error en el momento de la compilación, pero cuando ejecute la aplicación, obtendrá la excepción descrita en la pregunta.
La forma correcta:
haga clic derecho en el proyecto principal, elija Properties -> Android
, en la sección Biblioteca, agregue su proyecto de biblioteca de Android aquí. Consulte la guía oficial para desarrolladores Cómo hacer referencia a un proyecto de biblioteca . Esto debería solucionar todo su problema. También tenga en cuenta que debe utilizar la ruta relativa como referencia al proyecto de biblioteca de Android real, como se indica en Proyecto de biblioteca - Consideraciones de desarrollo .
Probé el código que me diste y funciona bien. Intente cambiar "extiende SimonSaysActivity" por simplemente "extiende Actividad" y compruebe usted mismo que funciona.
la razón por la que no funciona es que SimonSaysActivity no extiende la actividad (lo cual no creo que hayas cometido este error) o que el orden de la ruta de compilación es incorrecto.
para ir al orden de la ruta de construcción, vaya a:
project->properties->Java build path->order and export .
Mi orden básico es: proyecto src, proyecto gen, android 4.0.3, dependencias de Android.
Este problema suele ocurrir cuando usas bibliotecas.
Acabo de refactorizar una aplicación en una biblioteca de marco y una aplicación.
No estoy del todo seguro de lo que intenta decir aquí, pero el hecho de que haya utilizado la palabra "refactorizado" aquí me lleva a creer que está malinterpretando el concepto de proyecto de biblioteca.
Qué son los proyectos de biblioteca :
Un proyecto de biblioteca es un proyecto de desarrollo que contiene código fuente y recursos compartidos. Otros proyectos de Android pueden hacer referencia al proyecto de la biblioteca e incluir sus fuentes compiladas en sus archivos .apk en el momento de la compilación.
Qué proyectos de biblioteca no son :
Un proyecto de biblioteca se diferencia de un proyecto de Android estándar en que no puede compilarlo directamente en un solo .apk
archivo y ejecutarlo en un dispositivo Android. No puede utilizar un proyecto de Android como proyecto de biblioteca y luego hacer que otro proyecto de Android amplíe el proyecto de biblioteca. No funciona de esa manera.
Dicho esto, investigaría la estructura de su proyecto de biblioteca y me aseguraría de que lo haya configurado correctamente . Está bien usar su biblioteca para almacenar código/recursos compartidos, pero si su biblioteca intenta comportarse como si estuviera separada .apk
dentro del proyecto de la biblioteca, entonces probablemente haya hecho algo mal. Creo que ClassNotFoundException
se lanzaría una si este fuera el caso. Para solucionar el problema, simplemente crearía el proyecto de biblioteca desde cero, en lugar de intentar convertir el proyecto de Android en un proyecto de biblioteca. Eso evitará que te encuentres con pequeños y molestos errores.
No dude en publicar más código si aún tiene problemas. También deberías explicar un poco más la estructura (y el propósito) de tu proyecto de biblioteca... por qué decidiste usar uno, cómo lo creaste, etc.
Para Eclipse Kepler (Mac): presione Control y haga clic en proyecto -> Herramientas de Android -> agregar biblioteca de soporte
Tuve este problema con un proyecto en el que estaba trabajando, aunque mi caso fue diferente. Si alguien todavía no puede encontrar la solución a su problema, intente comprobar esto:
En eclipse:
Project properties -> Java Build Path -> Source tab
En el interior encontrará una lista con todas las carpetas de origen que se compilarán y colocarán en el apk generado cada vez para construir su proyecto (y /gen ). Normalmente:
>MyProject/gen
>MyProject/src
De lo que querrás estar seguro es de que dentro de cada una de tus carpetas de origen (excluye /gen , por lo que solo /src en este caso) el elemento Output folder
apunta a la carpeta de salida predeterminada, que es MyProject/bin/classes
. Haga esto seleccionando la carpeta Salida y haciendo clic en Eliminar en el conjunto de botones correcto (esto hará que apunte a la carpeta predeterminada).
Si no puede ver el subelemento Carpeta de salida, marque "Permitir carpetas de salida para las carpetas de origen" justo debajo de la lista.