UnsatisfiedLinkError in native method(本机方法中的 UnsatisfiedLinkError)
问题描述
我在本地方法中遇到不满意的链接错误
I m getting unsatisfied link error in native method
Logcat 主要异常
Logcat main exception
UnsatisfiedLinkError: Native method not found: rg.sqlite.database.sqlite.SQLiteConnection.nativeHasCodec:()Z
完整的Logcat
02-04 16:29:12.807: E/AndroidRuntime(5087): FATAL EXCEPTION: main
02-04 16:29:12.807: E/AndroidRuntime(5087): java.lang.UnsatisfiedLinkError: Native method not found: org.sqlite.database.sqlite.SQLiteConnection.nativeHasCodec:()Z
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteConnection.nativeHasCodec(Native Method)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteConnection.hasCodec(SQLiteConnection.java:160)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteDatabase.hasCodec(SQLiteDatabase.java:2195)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteConnectionPool.setMaxConnectionPoolSizeLocked(SQLiteConnectionPool.java:952)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteConnectionPool.<init>(SQLiteConnectionPool.java:153)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:179)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
02-04 16:29:12.807: E/AndroidRuntime(5087): at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
02-04 16:29:12.807: E/AndroidRuntime(5087): at com.example.samplesqlitedb.SearchDataDB.getAutoSuggestion(SearchDataDB.java:33)
02-04 16:29:12.807: E/AndroidRuntime(5087): at com.example.samplesqlitedb.MainActivity$2.onClick(MainActivity.java:56)
02-04 16:29:12.807: E/AndroidRuntime(5087): at android.view.View.performClick(View.java:4084)
02-04 16:29:12.807: E/AndroidRuntime(5087): at android.view.View$PerformClick.run(View.java:16966)
02-04 16:29:12.807: E/AndroidRuntime(5087): at android.os.Handler.handleCallback(Handler.java:615)
02-04 16:29:12.807: E/AndroidRuntime(5087): at android.os.Handler.dispatchMessage(Handler.java:92)
02-04 16:29:12.807: E/AndroidRuntime(5087): at android.os.Looper.loop(Looper.java:137)
02-04 16:29:12.807: E/AndroidRuntime(5087): at android.app.ActivityThread.main(ActivityThread.java:4745)
02-04 16:29:12.807: E/AndroidRuntime(5087): at java.lang.reflect.Method.invokeNative(Native Method)
02-04 16:29:12.807: E/AndroidRuntime(5087): at java.lang.reflect.Method.invoke(Method.java:511)
02-04 16:29:12.807: E/AndroidRuntime(5087): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-04 16:29:12.807: E/AndroidRuntime(5087): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-04 16:29:12.807: E/AndroidRuntime(5087): at dalvik.system.NativeStart.main(Native Method)
自定义 Java 文件 SQLiteConnectionhttps://www.dropbox.com/s/5ex6u9rzkwb7kqq/SQLiteConnection.java行号错误.160
Custom Java file SQLiteConnection https://www.dropbox.com/s/5ex6u9rzkwb7kqq/SQLiteConnection.java error on line no. 160
这是我编译并创建二进制libsqliteX.so"文件的源 cpp 文件 http://www.sqlite.org/android/tree?ci=trunk&re=jni|src/org/sqlite/data&expand一个>
Here is the source cpp files from where i have compiled and created the binary "libsqliteX.so" file http://www.sqlite.org/android/tree?ci=trunk&re=jni|src/org/sqlite/data&expand
我的 .so 文件 https://www.dropbox.com/s/d0u5pyhke54tcd6/libsqliteX.so
所以我认为我必须在本机方法中进行修改才能解决此问题
so i think i have to modify in the native method to resolve this problem
static jboolean nativeHasCodec(JNIEnv* env, jobject clazz){
#ifdef SQLITE_HAS_CODEC
return true;
#else
return false;
#endif
}
这里是 CDT GLOBAL BUILD 控制台
Here is CDT GLOBAL BUILD CONSOLE
**** Build of configuration Default for project CustomSqlite ****
D:softwareadt-bundle-windows-x86-20130522adt-bundle-windows-x86-20130522android-ndk-r9-windows-x86android-ndk-r9
dk-build.cmd all
"Compile++ thumb : sqliteX <= android_database_SQLiteCommon.cpp
"Compile++ thumb : sqliteX <= android_database_SQLiteConnection.cpp
"Compile++ thumb : sqliteX <= android_database_SQLiteGlobal.cpp
"Compile++ thumb : sqliteX <= android_database_SQLiteDebug.cpp
"Compile++ thumb : sqliteX <= JNIHelp.cpp
"Compile++ thumb : sqliteX <= JniConstants.cpp
"Compile thumb : sqliteX <= sqlite3.c
SharedLibrary : libsqliteX.so
Install : libsqliteX.so => libs/armeabi/libsqliteX.so
**** Build Finished ****
**** Build of configuration Default for project CustomSqlite ****
D:softwareadt-bundle-windows-x86-20130522adt-bundle-windows-x86-20130522android-ndk-r9-windows-x86android-ndk-r9
dk-build.cmd all
Install : libsqliteX.so => libs/armeabi/libsqliteX.so
**** Build Finished ****
所以我认为 .so 生成正确
so i think .so was generated properly
这是我的 Customsqlite.java
Here is my Customsqlite.java
它有方法
package org.sqlite.app.customsqlite;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import org.sqlite.database.DatabaseErrorHandler;
import org.sqlite.database.sqlite.SQLiteDatabase;
import org.sqlite.database.sqlite.SQLiteOpenHelper;
import org.sqlite.database.sqlite.SQLiteStatement;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
class DoNotDeleteErrorHandler implements DatabaseErrorHandler {
private static final String TAG = "DoNotDeleteErrorHandler";
public void onCorruption(SQLiteDatabase dbObj) {
Log.e(TAG,"Corruption reported by sqlite on database: " + dbObj.getPath());
}
}
public class CustomSqlite extends Activity {
private TextView myTV;
EditText query;
File DB_PATH;
String searchedword;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myTV = (TextView) findViewById(R.id.tv_widget);
query = (EditText) findViewById(R.id.query);
}
public void report_version() {
SQLiteDatabase db = null;
SQLiteStatement st;
String res;
db = SQLiteDatabase.openOrCreateDatabase(":memory:", null);
st = db.compileStatement("SELECT sqlite_version()");
res = st.simpleQueryForString();
myTV.append("SQLite version " + res + "
");
}
public void test_warning(String name, String warning) {
myTV.append("WARNING:" + name + ": " + warning + "
");
}
public void test_result(String name, String res, String expected) {
myTV.append(name + "... ");
if (res.equals(expected)) {
myTV.append("ok
");
} else {
myTV.append("FAILED
");
myTV.append(" res= "" + res + ""
");
myTV.append(" expected="" + expected + ""
");
}
}
/*
* * Test if the database at DB_PATH is encrypted or not. The db* is assumed
* to be encrypted if the first 6 bytes are anything* other than "SQLite".**
* If the test reveals that the db is encrypted, return the string*
* "encrypted". Otherwise, "unencrypted".
*/
public String db_is_encrypted() throws Exception {
FileInputStream in = new FileInputStream(DB_PATH);
byte[] buffer = new byte[6];
in.read(buffer, 0, 6);
String res = "encrypted";
if (Arrays.equals(buffer, (new String("SQLite")).getBytes())) {
res = "unencrypted";
}
in.close();
return res;
}
/*
* * Use a Cursor to loop through the results of a SELECT query.
*/
public void syno() throws Exception {
DB_PATH = new File("/storage/sdcard1/sk2.db");
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
Cursor c = db.rawQuery("SELECT synsetid, w2.lemma FROM sense LEFT JOIN word AS w2 ON w2.wordid=sense.wordid WHERE sense.synsetid IN (SELECT sense.synsetid FROM word AS w1 LEFT JOIN sense ON w1.wordid=sense.wordid WHERE w1.lemma='"+ searchedword+ "') AND w2.lemma<>'"+ searchedword + "'", null);
ArrayList<String> list1 = new ArrayList<String>();
if (c != null) {
if (c.getCount() > 0) {
c.moveToFirst();
do {
list1.add(c.getString(1));
} while (c.moveToNext());
}
myTV.append("
SYNONYM " + list1.toString());
}
db.close();
}
/*
* * If this is a SEE build, check that encrypted databases work.
*/
public void anto() throws Exception {
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
Cursor c = db.rawQuery("SELECT DISTINCT(w2.lemma) as lemma from word w1 left join sense se1 on w1.wordid = se1.wordid left join synset sy1 on se1.synsetid = sy1.synsetid left join lexlinkref on sy1.synsetid = lexlinkref.synset1id and w1.wordid = lexlinkref.word1id left join word w2 on lexlinkref.word2id = w2.wordid where w1.lemma = '"+ searchedword + "' and lexlinkref.linkid=30",null);
ArrayList<String> list1 = new ArrayList<String>();
if (c.getCount() > 0) {
c.moveToFirst();
do {
list1.add(c.getString(0));
} while (c.moveToNext());
}
myTV.append("
ANTONYMS "+list1.toString());
db.close();
}
class MyHelper extends SQLiteOpenHelper {
public MyHelper(Context ctx) {
super(ctx, DB_PATH.getPath(), null, 1);
}
public void onConfigure(SQLiteDatabase db) {
db.execSQL("PRAGMA key = 'secret'");
}
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE t1(x)");
}
public void onUpgrade(SQLiteDatabase db, int iOld, int iNew) {
}
}
/*
* * If this is a SEE build, check that SQLiteOpenHelper still works.
*/
public void def() throws Exception {
DB_PATH = new File("/storage/sdcard1/sk2.db");
String DEFINITION = "select pos, definition, sample FROM word INNER JOIN sense ON word.wordid = sense.wordid INNER JOIN synset ON sense.synsetid = synset.synsetid LEFT JOIN sample ON sample.synsetid = synset.synsetid WHERE lemma ='"+ searchedword + "'";
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
ArrayList<String> list1 = new ArrayList<String>();
Cursor mcursor = db.rawQuery(DEFINITION, null);
mcursor.moveToFirst();
if (mcursor.getCount() > 0) {
do {
list1.add(mcursor.getString(1));
} while (mcursor.moveToNext());
}
myTV.append("
DEFINATION " + list1.toString());
db.close();
}
public void run_the_tests(View view) {
System.loadLibrary("sqliteX");
myTV.setText("");
searchedword = query.getText().toString();
try {
report_version();
def();
syno();
anto();
} catch (Exception e) {
myTV.append("Exception: " + e.toString() + "
");
myTV.append(android.util.Log.getStackTraceString(e) + "
");
}
}
}
谢谢
推荐答案
我自己通过添加解决了这个问题
I have resolved this issue my self by adding
System.loadLibrary("sqliteX");
创建它们的每个方法
像这样:
public HashMap<String, ArrayList<String>> word_quiz(String qry) {
System.loadLibrary("sqliteX");
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH+ "/sk1.db", null);
Cursor mcursor = db.rawQuery(qry, null);
try {
mcursor.moveToFirst();
do {
list1.add(mcursor.getString(0));
list2.add(mcursor.getString(1));
} while (mcursor.moveToNext());
} catch (IndexOutOfBoundsException e) {
if (MainActivity.logcat_status) {
Log.e("Error", e + "");
}
}
mcursor.close();
mcursor = null;
HashMap<String, ArrayList<String>> final_list = new HashMap<String, ArrayList<String>>();
final_list.put("list1", list1);
final_list.put("list2", list2);
db.close();
return final_list;
}
现在可以正常使用了
我想我也可以使用构造函数来加载库sqliteX"
I think I can also use a constructor to load the library "sqliteX"
感谢大家考虑我的问题:)
Thanks guys for considering my question :)
这篇关于本机方法中的 UnsatisfiedLinkError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:本机方法中的 UnsatisfiedLinkError
基础教程推荐
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01