【问题标题】:java.lang.UnsatisfiedLinkError: No implementation found (NDK, Kotlin) - Fixedjava.lang.UnsatisfiedLinkError:未找到实现(NDK,Kotlin) - 已修复
【发布时间】:2018-12-26 15:37:36
【问题描述】:

我在 C 中使用 NDK 的文件如下,我查看了 Kotlin 中的包名称和 C 类 (NDK) 中的包名称,我没有发现任何区别:

 jstring Java_com_test1_app1_ui_BaseActivity_getLocalKeyOld(JNIEnv* env, jobject obj, jstring id) {
    const char *nativeString = (*env)->GetStringUTFChars(env, id, 0);

    char* deviceIdEncode = base64encode(nativeString);
    int lenght = strlen(deviceIdEncode);

    jstring result;
    if(lenght < 16) {
        result = (*env)->NewStringUTF(env,"+-0wef2ccfeqa0-+");
    } else if(lenght > 16) {
        char subbuff[17];
        memcpy( subbuff, &deviceIdEncode[0], 16 );
        subbuff[16] = '\0';
        result = (*env)->NewStringUTF(env,subbuff);
    } else {
        result = (*env)->NewStringUTF(env,deviceIdEncode);
    }
    return result;
}


jstring Java_com_test1_app1_ui_BaseActivity_getLocalKey(JNIEnv* env, jobject obj, jstring id) {
    const char *nativeString = (*env)->GetStringUTFChars(env, id, 0);

    char* deviceIdEncode = base64encodeNew(nativeString);
    int lenght = strlen(deviceIdEncode);

    jstring result;
    if(lenght < 16) {
        result = (*env)->NewStringUTF(env,"+-0wef2ccfeqa0-+");
    } else if(lenght > 16) {
        char subbuff[17];
        memcpy( subbuff, &deviceIdEncode[0], 16 );
        subbuff[16] = '\0';
        result = (*env)->NewStringUTF(env,subbuff);
    } else {
        result = (*env)->NewStringUTF(env,deviceIdEncode);
    }
    return result;
}

我的 Kotlin 类包是包 com.test1.app1.ui

我使用这些行加载 lib 库:

abstract class BaseActivity : AppCompatActivity() {

    companion object {
        @JvmStatic
        external fun getLocalKey(id: String): String

        @JvmStatic
        external fun getLocalKeyOld(id: String): String
    }

我正在使用 NDK 和 Kotlin。该应用程序启动良好,但是当我将其置于后台时,打开其他应用程序并尝试转到我的应用程序时它崩溃了。我可以得到下一个信息:

E/zygote: No implementation found for java.lang.String com.test1.app1.ui.BaseActivity.getLocalKey(java.lang.String) 
    (tried Java_com_test1_app1_ui_BaseActivity_getLocalKey and Java_com_test1_app1_ui_BaseActivity_getLocalKey__Ljava_lang_String_2)




    Process: com.testLab.app1, PID: 31409
        java.lang.UnsatisfiedLinkError: No implementation found 
        for java.lang.String com.test1.app1.ui.BaseActivity.getLocalKey(java.lang.String) (tried Java_com_test1_app1_ui_BaseActivity_getLocalKey and Java_com_test1_app1_ui_BaseActivity_getLocalKey__Ljava_lang_String_2)
            at com_test1_app1_ui_BaseActivity.getLocalKey(Native Method)
            at com.test1.app1.ui.BaseActivity$Companion.getLocalKey(BaseActivity.kt:1)
            at com.test1.app1.services.Utils.decryptLocal(Utils.kt:620)
            at com.test1.app1.services.Utils.getUserPhone(Utils.kt:352)
            at com.test1.app1.ui.login.LoginActivity.initActivity(LoginActivity.kt:77)
            at com.test1.app1.ui.login.WelcomeActivity.onCreate(WelcomeActivity.kt:24)
            at android.app.Activity.performCreate(Activity.java:7032)
            at android.app.Activity.performCreate(Activity.java:7023)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1236)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2814)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2943)
            at android.app.ActivityThread.-wrap11(Unknown Source:0)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1630)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:164)
            at android.app.ActivityThread.main(ActivityThread.java:6626)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)

FIX(对我有用)

我通知我在 SplashActivity 调用 System.loadLibrary("nameofyourCFile")(SplashActivity 扩展 BaseActivity),但其余活动没有加载 C 文件,因为当我去后台并返回 SplashActivity 时没有再次启动,所以我的库没有从任何地方加载。我将 System.loadLibrary() 放在我的 BaseActivity 中,它就可以工作了!

附:感谢@GenoChen 先生 的帮助和时间!

【问题讨论】:

  • 在我的记忆中,JNI 函数签名类似于JNIEXPORT &lt;return_type&gt; JNICALL &lt;function_name&gt;(&lt;param_list&gt;)。我不确定JNIEXPORTJNICALL 的缺失是否会导致问题。 (我也不知道它们的意思。)
  • @GenoChen 谢谢!感谢您的评论,我将开始查看您的信息。如果您以后有其他想法,欢迎您!祝你有美好的一天!
  • 再次仔细阅读您的问题后...您的意思是,您第一次启动应用程序时可以,但是当您切换到其他应用程序并返回时崩溃?那么也许我的评论是错误的......也许加载的库在交换到其他应用程序时被“解构”了?那么问题可能是你是如何加载那个库的?
  • 我已经用这些信息更新了我的问题! :) @GenoChen
  • @JvmStatic external fun 对于 Java-C 互操作是不够的,需要 System.loadLibrary()

标签: android string kotlin android-ndk unsatisfiedlinkerror


【解决方案1】:

System.loadLibrary()(可能在 companion object {} 块中的 init {} 块内)对于 Java 运行时查找本机库(包含函数的“核心”)在哪里是必需的。仅仅一个@JvmStatic external fun(它只是一个“表面”或“界面”)是不够的。

如果您在加载该库之前调用了这些外部函数,您将得到这样的异常。

可能是正确的方法(直接从新 Android Studio 项目的模板中复制):

class MainActivity : Activity()
{

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Example of a call to a native method
        sample_text.text = stringFromJNI()
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    external fun stringFromJNI(): String

    companion object
    {

        // Used to load the 'native-lib' library on application startup.
        init
        {
            System.loadLibrary("native-lib")
        }
    }
}

像原来的问题一样将external fun 移动到companion object {} 中是可以的。

【讨论】:

  • 谢谢!!我会给你它的功劳。我在几分钟前找到了它,但你帮了我很多!祝你今天过得愉快 !!编码愉快!
  • @Cristofer 祝你好运:-)
猜你喜欢
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 2017-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多