Android JNI 普通方法和静态方法详解
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的静态方法和普通方法有什么区别?
()很多人可能都不清楚,如果想知道的可以了解一下。
比如下面一段代码:
()//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
共勉: 今天很残酷,明天更残酷,后天很美好 …