2014-02-27 11 views
5

Hiee, ich benutze sqlcipher, um die Datenbank zu lesen, aber vor dem Lesen der Daten gibt es die folgenden Fehler. Unten ist mein Logcat bitte einen Blick.Ich benutze SQLCIPHER zu lesen oder zu schreiben Datenbank bekommen Fehler

E/AndroidRuntime(21826): FATAL EXCEPTION: main 
02-27 11:33:10.608: E/AndroidRuntime(21826): java.lang.UnsatisfiedLinkError: Native  method not found: net.sqlcipher.database.SQLiteDatabase.dbopen:(Ljava/lang/String;I)V 
02-27 11:33:10.608: E/AndroidRuntime(21826): at net.sqlcipher.database.SQLiteDatabase.dbopen(Native Method) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at net.sqlcipher.database.SQLiteDatabase. <init>(SQLiteDatabase.java:1942) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1920) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at example.SQLDemoActivity.onCreate(SQLDemoActivity.java:19) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.Activity.performCreate(Activity.java:5020) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2211) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread.access$600(ActivityThread.java:149) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1300) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.os.Handler.dispatchMessage(Handler.java:99) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.os.Looper.loop(Looper.java:153) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread.main(ActivityThread.java:4987) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at java.lang.reflect.Method.invokeNative(Native Method) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at java.lang.reflect.Method.invoke(Method.java:511) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584) 
02-27 11:33:10.608: E/AndroidRuntime(21826): at dalvik.system.NativeStart.main(Native Method) 

Unten ist der Link, von wo aus ich diese sqlcipher Klasse erhalten haben, die ich versuche, sqlcipher link

Dies ist die Klasse zu laufen, wo ich SQLiteDatabase.loadLibs (this) bin Anruf bitte ein Blick

public class SQLDemoActivity extends Activity 
     { 
    EventDataSQLHelper eventsData; 



    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
    super.onCreate(savedInstanceState); 

//you must set Context on SQLiteDatabase first 
SQLiteDatabase.loadLibs(this); 

String password = "foo123"; 

eventsData = new EventDataSQLHelper(this); 

//then you can open the database using a password 
SQLiteDatabase db = eventsData.getWritableDatabase(password); 

for (int i = 1; i < 100; i++) 
    addEvent("Hello Android Event: " + i, db); 

    db.close(); 

    db = eventsData.getReadableDatabase(password); 

    Cursor cursor = getEvents(db); 
    showEvents(cursor); 

    db.close(); 

    } 

    @Override 
    public void onDestroy() { 
    eventsData.close(); 
    } 

    private void addEvent(String title, SQLiteDatabase db) { 

    ContentValues values = new ContentValues(); 
    values.put(EventDataSQLHelper.TIME, System.currentTimeMillis()); 
      values.put(EventDataSQLHelper.TITLE, title); 
    db.insert(EventDataSQLHelper.TABLE, null, values); 
    } 

    private Cursor getEvents(SQLiteDatabase db) { 

    Cursor cursor = db.query(EventDataSQLHelper.TABLE, null, null, null, null, 
    null, null); 

    startManagingCursor(cursor); 
    return cursor; 
    } 

    private void showEvents(Cursor cursor) { 
StringBuilder ret = new StringBuilder("Saved Events:\n\n"); 
while (cursor.moveToNext()) { 
    long id = cursor.getLong(0); 
    long time = cursor.getLong(1); 
    String title = cursor.getString(2); 
    ret.append(id + ": " + time + ": " + title + "\n"); 
} 

Log.i("sqldemo",ret.toString()); 
    } 
} 

und darunter ist die Methode Körper

public class SQLiteDatabase extends SQLiteClosable { 
private static final String TAG = "Database"; 
private static final int EVENT_DB_OPERATION = 52000; 
private static final int EVENT_DB_CORRUPT = 75004; 

public int status(int operation, boolean reset){ 
    return native_status(operation, reset); 
} 

private static void loadICUData(Context context, File workingDir) 
{ 

    try { 
     File icuDir = new File(workingDir, "icu"); 
     if(!icuDir.exists()) icuDir.mkdirs(); 
     File icuDataFile = new File(icuDir, "icudt46l.dat"); 
     if(!icuDataFile.exists()) { 
      ZipInputStream in = new ZipInputStream(context.getAssets().open("icudt46l.zip")); 
      in.getNextEntry(); 
      OutputStream out = new FileOutputStream(icuDataFile); 
      byte[] buf = new byte[1024]; 
      int len; 
      while ((len = in.read(buf)) > 0) 
      { 
       out.write(buf, 0, len); 
      } 
      in.close(); 
      out.flush(); 
      out.close(); 
     } 
    } 
    catch (Exception e) 
    { 
     Log.e(TAG, "Error copying icu data file", e); 
    } 
} 

public static void loadLibs (Context context) 
{ 
    loadLibs(context, context.getFilesDir()); 
} 





    public static void loadLibs (Context context, File workingDir) 
{ 
    System.loadLibrary("stlport_shared"); 
    System.loadLibrary("sqlcipher_android"); 
    System.loadLibrary("database_sqlcipher"); 

    boolean systemICUFileExists = new File("/system/usr/icu/icudt46l.dat").exists(); 

    String icuRootPath = systemICUFileExists ? "/system/usr" : workingDir.getAbsolutePath(); 
    setICURoot(icuRootPath); 
    if(!systemICUFileExists) 
    { 
     loadICUData(context, workingDir); 
    } 
} 


    } 

Antwort

9

Dieser Fehler tritt normalerweise auf, wenn Sie vor dem Versuch, die Datenbank zu verwenden, SQLiteDatabase.loadLibs() nicht aufgerufen haben.

+0

pls haben einen Blick auf mein Code, habe ich verwendet, eine Methode mit dem Namen loadLibs() – Yushi

+0

ich habe das gleiche getan, schauen Sie, ich habe den Code der Klasse, wo ich loadLibs() aufgerufen habe. Nach all dem habe ich diese Ausnahme – Yushi

+1

@Yushi: Ihr Code und Ihre Stack-Trace stimmen nicht überein. Ihr Stack-Trace zeigt an, dass Ihr 'onCreate()' den Konstruktor für 'SQLiteDatabase' aufruft. – CommonsWare

3

Die UnsatisfiedLinkError ist aufgrund der nativen Bibliotheken nicht in Ihrer Anwendung enthalten. Ein Beispiel für die Integration von SQLCipher mit einer vorhandenen Anwendung finden Sie im Lernprogramm this. Sehen Sie sich alternativ den SQLCipher für Android test suite an.

1

@CommonsWare ist korrekt und Sie haben es abgelehnt.

Wenn Ihre App aus einem langen Schlafzustand wieder aufgenommen wird, wurden die Bibliotheken ausgelagert, und der Wiederherstellungsstatus stürzt ab, da keine Bibliotheken vorhanden sind.

Setzen Sie Ihre SQLiteDatabase.loadLibs (this);

vor super.onCreate (savedInstanceState)
@Override 
public void onCreate(Bundle savedInstanceState) { 

    //you must set Context on SQLiteDatabase first 
    SQLiteDatabase.loadLibs(this); 

    super.onCreate(savedInstanceState); 
+0

Willst du sagen, dass es nicht ausreicht, etwas wie 'static boolean 'zu tun? LIBS_LOADED = false; ... if (! LIBS_LOADED) {SQLiteDatabase.loadLibs (this); LIBS_LOADED = Wahr; } '. Wenn ich Sie richtig verstehe, bleibt LIBS_LOADED wahr, obwohl die Bibliotheken möglicherweise wiederverwendet wurden. Bitte können Sie auf einige Beweise verweisen, um dies zu unterstützen? –

+0

Ich habe den Stack-Trace möglicherweise falsch gelesen. Mein Fall war das super.onCreate (savedInstanceState); Erstellte andere Fragmente, die SQLCipher referenzierten, was laut dem, was ich erwähnte, definitiv geschah. In Ihrem Fall wurden die geteilten Objekte einfach nicht eingefügt, wie Nick darauf hingewiesen hat. –

0

Wenn SQLiteDatabase.loadLibs() ist, so stellen Sie sicher, dass Sie diese Zeilen hinzufügen Datei ProGuard:

#Keep SQLCypher classes 
-keep class net.sqlcipher.** { *; }