Android JNI 普通方法和静态方法详解

2024-03-11 6014阅读

Android JNI 普通方法和静态方法详解

文章目录

  • Android JNI 普通方法和静态方法详解
    • 一、前言
    • 二、Android JNI 普通方法和静态方法
    • 1、native 的静态方法和普通方法
        • (1) JNI定义nativie普通方法和静态方法
        • (2)jni native-lib.cpp中的代码:
        • (3)调用JNI方法的代码
        • Java中的普通方法和静态方法有以下区别:
        • 2、cpp调用Java普通方法和静态方法区别
          • (1) Java定义普通方法和静态方法
          • (2)jni native-lib.cpp中的代码:
          • (3)调用JNI方法的代码
          • 三、其他
            • 1、Android JNI 普通方法和静态方法小结
            • 2、Android Jni的介绍和简单Demo实现
            • 3、 Android JNI复杂用法,回调,C++中调用Java方法
            • 共勉: 今天残酷,明天更残酷,后天很美好 ...

              一、前言

              Android Jni中Java的静态方法和普通方法有什么区别?

              Android JNI 普通方法和静态方法详解 第1张
              ()

              很多人可能都不清楚,如果想知道的可以了解一下。

              比如下面一段代码:

              Android JNI 普通方法和静态方法详解 第2张
              ()
              //1、native 的静态方法和普通方法
                  public native void normalNativeMethod(); // 声明普通native方法
                  public static native void staticNativeMethod(); // 声明静态native方法
              //2、Java 的普通方法和静态方法,C++调用过来的处理区别?
                  // 普通方法
                  public void normalMethod() {
                      System.out.println("这是一个普通方法");
                  }
                  // 静态方法
                  public static void staticMethod() {
                      System.out.println("这是一个静态方法");
                  }
              

              JNI的静态方法包含native的静态方法,以及C++调用Java 的静态方法。

              上面两种不同的静态方法,对于JNI来说有啥区别?

              这个问题很少人会关注,一个是因为很少会静态方法调用JNI或者回调静态的Java方法;

              另外一个是因为知道了或者调试过就不难了,所以很多人觉得没必要讲解和记录。

              但是对于JNI 的初学者来说静态方法还是比较陌生的,很容易会懵逼的,不知道有啥区别。

              本文主要讲解一下上面两种静态方法在JNI中的区别,有兴趣的可以看看。

              二、Android JNI 普通方法和静态方法

              1、native 的静态方法和普通方法

              这个其实是很简单的,就是类里面的方法和对象的对象里面的方法的区别,这个和Java是完全一样的。

              调用nativie的静态方法,只要类名就行,比如:MyClass.staticMethod();

              调用nativie 的普通方法就要对象了,如果是本类就是隐藏的this,比如:myClass.method()。

              并且Java中定义的nativie静态方法和普通写法,在cpp里面的写法都是一样的。

              示例代码如下:

              (1) JNI定义nativie普通方法和静态方法
              public class MyJNIClass {
                  // 声明普通native方法
                  public native void normalNativeMethod();
                  
                  // 声明静态native方法
                  public static native void staticNativeMethod();
                  
                  static {
                      System.loadLibrary("myjni"); // 加载C++库
                  }
              }
              

              这里可以看到jni的库加载的代码就是在static里面的,

              所以不管是静态方法还是普通方法都是不必担心库加载的问题。

              (2)jni native-lib.cpp中的代码:
              #include 
              extern "C"  JNIEXPORT void JNICALL Java_com_example_myapp_MyJNIClass_normalNativeMethod(JNIEnv* env, jobject obj) {
                      // 在这里编写普通native方法的代码
              }
                  
              extern "C"JNIEXPORT void JNICALL Java_com_example_myapp_MyJNIClass_staticNativeMethod(JNIEnv* env, jclass cls) {
                      // 在这里编写静态native方法的代码
              }
              

              对于cpp代码来说是一点区别都没有的,命名规则那些都是一样的。

              (3)调用JNI方法的代码

              在Android项目中的MainActivity中,调用这些JNI方法:

              public class MainActivity extends AppCompatActivity {
                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      setContentView(R.layout.activity_main);
                      
                      MyJNIClass myJNI = new MyJNIClass();
                      
                      // 调用普通native方法
                      myJNI.normalNativeMethod();
                      
                      // 调用静态native方法
                      MyJNIClass.staticNativeMethod();
                  }
              }
              

              最大的区别就是调用的时候了,类和类的对象的区别。

              所以native普通方法和静态方法,和Java的普通方法和静态方法是一样的,

              就是调用的时候需要到的类和类的对象的区别,

              静态方法需要类就可以调用,普通方法要类的对象才可以调用。

              非要说点其他区别完整的,就把Java那套搬过去就行:

              Java中的普通方法和静态方法有以下区别:
              1、调用方式不同:
              普通方法通过对象实例调用,而静态方法通过类名直接调用。
              2、内存分配不同:
              普通方法在每个对象实例中都有一份独立的内存空间,
              而静态方法在类加载时就已经分配了内存空间,所有对象共享该方法。
              3、访问权限不同:
              普通方法可以访问类的所有成员(包括静态成员和非静态成员),而静态方法只能访问类的静态成员。
              4、静态方法不能访问非静态成员:
              由于静态方法在对象创建之前就已经存在,所以无法访问需要通过对象实例才能访问的非静态成员。
              5、静态方法可以直接调用:
              由于静态方法不依赖于对象实例,所以可以在没有创建对象的情况下直接调用。
              6、静态方法不能被重写:
              由于静态方法是通过类名直接调用的,所以无法被子类重写。
              

              2、cpp调用Java普通方法和静态方法区别

              先看一下下面的示例代码:

              (1) Java定义普通方法和静态方法
              public class MyJNIClass {
                  // 普通方法
                  public void normalMethod() {
                      System.out.println("这是一个普通方法");
                  }
                  
                  // 静态方法
                  public static void staticMethod() {
                      System.out.println("这是一个静态方法");
                  }
              }
              

              这里就是一个最普通的Java类,定义了一个普通方法和静态方法。

              后面cpp代码会调用Java代码,执行程序后就可以看到打印。

              (2)jni native-lib.cpp中的代码:
              #include 
              extern "C"  JNIEXPORT void JNICALL Java_com_example_myapp_MainActivity_callNormalMethod(JNIEnv* env, jobject obj) {
                      // 获取MyJNIClass类
                      jclass cls = env->FindClass("com/example/myapp/MyJNIClass");
                      
                      // 获取普通方法的方法ID
                      jmethodID methodId = env->GetMethodID(cls, "normalMethod", "()V");
                      
                      // 创建MyJNIClass对象
                      jobject jniObj = env->AllocObject(cls);
                      
                      // 调用普通方法
                      env->CallVoidMethod(jniObj, methodId);
                  }
                  
              extern "C" JNIEXPORT void JNICALL Java_com_example_myapp_MainActivity_callStaticMethod(JNIEnv* env, jobject obj) {
                      // 获取MyJNIClass类
                      jclass cls = env->FindClass("com/example/myapp/MyJNIClass");
                      
                      // 获取静态方法的方法ID
                      jmethodID methodId = env->GetStaticMethodID(cls, "staticMethod", "()V");
                      
                      // 调用静态方法
                      env->CallStaticVoidMethod(cls, methodId);
                  }
              

              其实关键就在这里,静态方法和普通方法调用的api函数是不一样的;

              具体区别:

              1、获取方法签名的api函数不同
              GetMethodID 是获取普通方法签名id的方法;GetStaticMethodID是获取静态方法签名id的方法;
              2、需要的调用对象不同
              静态方法使用类就可以调用,普通方法还有获取到类的对象
              3、反射执行调用普通方法和静态方法的api函数不同
              CallVoidMethod 是普通方法执行的api函数,CallStaticVoidMethod 是静态方法执行的api函数;
              这里只是一个举例,如果不是void的方法,那么api函数是不同的,
              比如调用一个返回Int的方法,反射调用的api函数就是 CallIntMethod,其他的方法以此类推
              
              (3)调用JNI方法的代码

              在Android项目中的MainActivity中,调用这些JNI方法:

              public class MainActivity extends AppCompatActivity {
                  static {
                      System.loadLibrary("myjni"); // 加载C++库
                  }
                  
                  public native void callNormalMethod();
                  public native void callStaticMethod();
                  
                  @Override
                  protected void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      setContentView(R.layout.activity_main);
                      
                      // 调用普通方法
                      callNormalMethod();
                      
                      // 调用静态方法
                      callStaticMethod();
                  }
              }
              

              执行程序后,就可以看到 MyJNIClass 类里面的静态方法和普通方法的打印日志。

              三、其他

              1、Android JNI 普通方法和静态方法小结

              Java中定义的普通native方法和静态nativie方法区别:

              两种方法没啥太大区别,cpp代码的写法是一样的,
              区别就是Java的普通方法和静态方法的区别,使用的时候需要的调用对象不同,
              普通方法是类的对象进行调用,静态方法是类直接进行调用。
              

              cpp调用Java普通方法和静态方法区别:

              cpp代码里面的实现api函数不同,调用静态方法获取类,调用普通方法要获取类的对象,
              静态方法的调用一般是api函数里面多了Static关键字。
              

              本文的内容精华,就是上面几句。

              理解一下,或者操作试试,就会更加印象深刻。

              2、Android Jni的介绍和简单Demo实现

              之前写的文章,包含了简单使用到的api函数

              https://blog.csdn.net/wenzhi20102321/article/details/136291126

              3、 Android JNI复杂用法,回调,C++中调用Java方法

              JNI C++调用Java代码实现和相关知识 :

              https://blog.csdn.net/wenzhi20102321/article/details/136419405

              共勉: 今天很残酷,明天更残酷,后天很美好 …


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]