2012-12-14 10 views
7

ottenere questo errore quando uso SQLiteDatabase come CloseableSQLiteDatabase 'non implementa l'interfaccia'

Ho un progetto di esempio per ricrearlo:

https://github.com/blundell/SQLDatabaseError

Con una classe che estende SQLiteOpenHelper : trace

public class DatabaseHelper extends SQLiteOpenHelper { 

.... 

public void openAndCloseDatabase() { 
    SQLiteDatabase database = getWritableDatabase(); 

    close(database); 
} 

private void close(Closeable database) { 
    try { 
     if (database != null) { 
      database.close(); 
     } 
    } catch (Exception e) { 
     Log.e("Error", "Oh no!", e); 
    } 
} 

} 

Stack:

12-14 12:23:43.719: E/AndroidRuntime(5179): FATAL EXCEPTION: main 
12-14 12:23:43.719: E/AndroidRuntime(5179): java.lang.IncompatibleClassChangeError: interface not implemented 
12-14 12:23:43.719: E/AndroidRuntime(5179): at com.blundell.sqldatabasecursorerror.DatabaseHelper.close(DatabaseHelper.java:35) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at com.blundell.sqldatabasecursorerror.DatabaseHelper.openAndCloseDatabase(DatabaseHelper.java:29) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at com.blundell.sqldatabasecursorerror.MainActivity.onCreate(MainActivity.java:13) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1623) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1675) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at android.app.ActivityThread.access$1500(ActivityThread.java:121) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:943) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at android.os.Handler.dispatchMessage(Handler.java:99) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at android.os.Looper.loop(Looper.java:130) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at android.app.ActivityThread.main(ActivityThread.java:3701) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at java.lang.reflect.Method.invokeNative(Native Method) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at java.lang.reflect.Method.invoke(Method.java:507) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624) 
12-14 12:23:43.719: E/AndroidRuntime(5179):  at dalvik.system.NativeStart.main(Native Method) 

API:

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

http://developer.android.com/reference/android/database/sqlite/SQLiteClosable.html

http://developer.android.com/reference/java/io/Closeable.html

Questo dovrebbe funzionare non dovrebbe?

public final class SQLiteDatabase extends SQLiteClosable 
>> 
public abstract class SQLiteClosable extends Object implements Closeable 
>> 
public interface Closeable 

non funziona:

  • Xperia Play Android 2.3.4
  • Motorola Xoom Android 4.0.4

funziona:

  • Samsung Galaxy Nexus Android 4,2
+0

'La classe pubblica DatabaseHelper estende anche gli oggetti SQLiteOpenHelper Closeable'. – waqaslam

+1

(non uno sviluppatore Android) IncompatibleClassChangeError sembra che tu stia compilando e correndo contro diverse versioni della libreria. – ignis

+0

Vedere la risposta accettata qui: http://stackoverflow.com/questions/1980452/what-causes-java-lang-incompatibleclasschangeerror –

risposta

6

Va bene, trovato il problema in the Change Notes for 4.1 (API Level 16):

android.database.sqlite.SQLiteClosable attrezzi java.io.Closeable solo dalle API livello 16. Prima di allora, erano estranei (anche se entrambe le interfacce esistito sin dall'inizio).

Quindi è necessario utilizzare SQLiteClosable direttamente se si desidera che il codice sia retrocompatibile.

Probabilmente è anche utile installare l'SDK per la versione più bassa che si desidera supportare e provare a creare con esso, quindi questo sarebbe stato rilevato dal compilatore.

+0

Sarebbe bello se questo fosse notato anche in Javadoc per SQLiteClosable. – Thilo

+0

Grazie, buon posto! Peccato che sia da api16 altro codice di sicurezza per scrivere. Sì, Lint attira normalmente richieste di livello API ovvie, ma come dici tu sono entrambe disponibili dall'API 1. Potresti creare un avviso Lint e inserirlo. – Blundell

+0

Appena stato morso di nuovo da questo! Questa volta con 'java.util.Scanner' http://developer.android.com/sdk/api_diff/19/changes/java.util.Scanner.html – Blundell