zoukankan      html  css  js  c++  java
  • Class doesn't implement Cloneable之怪象

    1. 报错:

    1. 11-20 14:06:10.89: W/dalvikvm(10190): threadid=15: thread exiting with uncaught exception (group=0x4001d400)   
    2. 11-20 14:06:10.360: E/AndroidRuntime(10190): FATAL EXCEPTION: GLThread 10  
    3. 11-20 14:06:10: E/AndroidRuntime(10190): java.lang.CloneNotSupportedException: Class doesn't implement Cloneable   
    4. 11-20 14:06:10.360: E/AndroidRuntime(10190):    at java.lang.Object.clone(Object.java:79)   
    5. 11-20 14:06:10.360: E/AndroidRuntime(10190):    at com.jnitest.nativetest(Native Method)

    2. 现场说明:

       在进行android项目开发时, 想用java代码调用jni的test函数,, 而且再通过c的callCallBack函数, 回调到java的onCallback函数., 发生以上错误.

    3. 代码:(这里仅仅列出重要的,关键的代码.)

     java代码:

    public class NativeClass {

    private static String TAG= "NativeClass";

    static {
            System.loadLibrary("test-jni");
        }

    public static int onCallBack(int event, int type,String str) {  //回调回来的回调函数
      Log.i(TAG, "onCallBack======= " + event);
      Log.i(TAG, "onCallBack======= " + type);

    Log.i(TAG, "onCallBack======= " + str);

    return event;

    }

    public static native int test();  //native函数

    c代码:

    jobject my_obj;
    JNIEnv* my_env;


    extern "C" int callCallBack(int event, int type, const char *str) ;

    extern "C"
    {

    //用于调用java的callback
    int  callCallBack(int event, int type, const char *str)
    {
        int err = 1000;
     jclass objClass = (my_env)->FindClass("com/jnitest/native/NativeClass");
     if(!objClass) {
      return -1;
     }
     //获取并调用java层的onCallBack函数
     jmethodID methodId = (my_env)->GetStaticMethodID(objClass, "onCallBack", "(IILjava/lang/String;)I");
     if (methodId == 0) {
      LOGDV("here can not find method %s ", "onCallBack");
     } else {
      jstring data = (update_env)->NewStringUTF(str));
      
      err = (my_env)->CallStaticIntMethod(objClass, methodId, event, type, data);
      if(data)  my_env->DeleteLocalRef(data);
     }

     my_env->DeleteLocalRef(objClass);
     
     
     return err;

    }

    //jni native函数.
    JNIEXPORT jstring JNICALL
    Java_com_jnitest_native_test( JNIEnv* env, jobject thiz,jstring testStr )
    {
        my_env = env; //必须保存,用于在回调的时候获取回调函数所在的class.
     my_obj = thiz;  //在本程序中,没实用到这个变量.
        const char *test_char = (env)->GetStringUTFChars(testStr, NULL);
     
     //调用callCallBack
     int i = callCallBack(0,1,test_char);

        return (env)->NewStringUTF(test_char);

    }
    }

    測试代码:

    maintest.java:

    void testFunc() {

    String s = NativeClass.test("ssss");

        Log.i("jniTest", " testFunc  s = " + s);

    }

    測试结果:

    onCallBack=======0

    onCallBack=======1

    onCallBack=======ssss

     testFunc  s =ssss

    4. 分析与 解决:

    分析,:

    依据错误提示:

    1).  有clone相关错误;

    2)   就发生在NativeClass的test函数中.

    3). 那么, 是哪个类没有进行clone?

    或者, 根本就不是clone的原因?

     4). NativeClass中,没有数据成员, 理论上讲,就不须要进行克隆.所以,应该不是NativeClass克隆的原因.

    5). 在jni的test函数中,有对于my_obj的赋值,会不会是这个变量的赋值导致的呢?

    解决:  因为my_obj没实用到(本来赋值后想用的), 并且可能会引起错误,所以,将这个变量的声明和赋值语句都去掉,

     

    再測试,程序正常执行.

    5. 总结:

    1)  由java调用c时,一定要注意參数的正确传递.

    2)  本例展示了怎样用java调用c,再由c调用到java的过程.

    3) 本例来源于android程序开发.

  • 相关阅读:
    [洛谷P2745] [USACO5.3]窗体面积Window Area
    [洛谷P2751] [USACO4.2]工序安排Job Processing
    [洛谷P2738] [USACO4.1]篱笆回路Fence Loops
    [洛谷P4609] [FJOI2016]建筑师
    [洛谷P3228] [HNOI2013]数列
    解决Qt5使用SSL的“qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method”错误
    qt查看是否支持SSL
    qt获取依赖的openssl的版本
    qt关闭ssl验证,解决不能正常使用自签署ssl证书API的问题
    使用OpenSSL创建HTTPS所使用的SSL证书
  • 原文地址:https://www.cnblogs.com/llguanli/p/6853633.html
Copyright © 2011-2022 走看看