多线程

  • 三种方式创建线程

implements Runnable. #实现接口
extends Thread. #继承
Thread thread = new Thread(). #匿名内部类
  • 方法

start() #启动线程
run() #内容
setname() #线程名更改
sleep() #休眠
setpriority() #优先级
interrupt() #中断
join() #最大终止时间    

同步锁:synchronized (买票软件 防止固定数量的票被进行多次销售,类似不能同时多个线程访问同一个资源)

  互斥锁:reentrantck (和同步锁差不多)

     condition (搞不明白)

     volatile (主要用于数据的同步 加锁的话会在操作数据之后第一时间进行更新和同步)

反射 

运行判断任意对象所属类

运行时调用任何一个类的方法

运行时构造任意类的对象

运行时查看任意类的成员变量和方法

  • 获取class对象

  • 创建实例(使用class对象创建 和smail中 new-instance应该是一个意思)

java和c的数据交互

  • Java代码

System.out.println(frmojnitest());
System.out.println(JavaToJni("=====c++====="));

public native String frmojnitest();
public native ArrayList<Character> JavaToJni(String str);
  • c代码

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_hellojni_MainActivity_frmojnitest(JNIEnv *env, jobject thiz) {
    // TODO: implement frmojnitest()
//    int result =123456;
//    std::string resultString = std::to_string(result);
      std::string resultString = "这段话来自c++";
    // 返回字符串
    return env->NewStringUTF(resultString.c_str());
}


extern "C"
JNIEXPORT jobject JNICALL
Java_com_example_hellojni_MainActivity_JavaToJni(JNIEnv *env, jobject thiz, jstring str) {
    // TODO: implement JavaToJni()
    const char *inputString = env->GetStringUTFChars(str, nullptr);
    std::vector<char> resultVector;
    for (size_t i = 0; i < strlen(inputString); ++i) {
        resultVector.push_back(inputString[i]);
    }
    env->ReleaseStringUTFChars(str, inputString);
    jclass arrayListClass = env->FindClass("java/util/ArrayList");
    jmethodID arrayListConstructor = env->GetMethodID(arrayListClass, "<init>", "()V");
    jmethodID arrayListAdd = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
    jobject resultArrayList = env->NewObject(arrayListClass, arrayListConstructor);
    for (char character : resultVector) {
        jchar javaChar = static_cast<jchar>(character);
        jobject javaCharObject = env->NewObject(env->FindClass("java/lang/Character"), env->GetMethodID(env->FindClass("java/lang/Character"), "<init>", "(C)V"), javaChar);
        env->CallBooleanMethod(resultArrayList, arrayListAdd, javaCharObject);
        env->DeleteLocalRef(javaCharObject);
    }
    return resultArrayList;
}

反射实例化TestData对象 并将对象引用return

#参数为全限定类名 要用jclass去定义 
findclass("str"). 
#参数为对象 需要通过java传一个对象到JNI
env->GetObjectClass(obj). 
#获取构造函数id 也可以用来获取方法的id 参数有三个 后两个是方法签名 第一个是class jobject定义
GetMethodID(class,"","")
#实例化对象 参数为class和id jmethodID定义
NewObject(class,init)
extern "C"
JNIEXPORT jobject JNICALL
Java_com_example_hellojni_MainActivity_test(JNIEnv *env, jobject thiz) {
    // TODO: implement test()
    jclass testDataClass = env->FindClass("com/example/hellojni/TestData");
    jmethodID constructor = env->GetMethodID(testDataClass,"<init>", "(Ljava/lang/String;ICZJFD)V");
    jstring strParam = env->NewStringUTF("example_string");
    jint iParam = 42;
    jchar cParam = 'a';
    jboolean bParam = JNI_TRUE;
    jlong lParam = 1234567890L;
    jfloat fParam = 3.14f;
    jdouble dParam = 2.71828;
    jobject testDataObj = env->NewObject(testDataClass, constructor, strParam, iParam, cParam, bParam, lParam, fParam, dParam);
    env->DeleteLocalRef(strParam);
    return testDataObj;
}

反射调用TestData对象的toString()方法 并将结果return

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_hellojni_MainActivity_test3(JNIEnv *env, jclass clazz, jobject context) {
    // TODO: implement test3()
    jclass testDataClass = env->FindClass("com/example/hellojni/TestData");
    jmethodID toStringMethod = env->GetMethodID(testDataClass,"toStringInternal", "()Ljava/lang/String;" );
    jmethodID constructor = env->GetMethodID(testDataClass,"<init>", "(Ljava/lang/String;ICZJFD)V");
    jstring strParam = env->NewStringUTF("liuliuliuliu");
    jint iParam = 42;
    jchar cParam = 'a';
    jboolean bParam = JNI_TRUE;
    jlong lParam = 1234567890L;
    jfloat fParam = 3.14f;
    jdouble dParam = 2.71828;
    jobject testDataObj = env->NewObject(testDataClass, constructor, strParam, iParam, cParam, bParam, lParam, fParam, dParam);
    jstring result = (jstring)env->CallObjectMethod(testDataObj, toStringMethod);
    return result;
}

获得类的[成员字段描述] 修改类对象的[成员字段]的值

#获取属性 三个参数 类,成员变量的名字,类型
GetFieldID(class,"name","type")
#获取静态属性 三个参数 类,成员变量的名字,类型
GetStaticFieldID(class,"name","type")
#设置属性 三个参数 对象,id,值
Set<type>Field(obj,fileid,value)
extern "C"
JNIEXPORT void JNICALL
Java_com_example_hellojni_TestData_changeFields(JNIEnv *env, jobject thiz) {
    // TODO: implement changeFields()
    jclass cls = env->GetObjectClass(thiz);
    jfieldID strField = env->GetFieldID(cls, "str", "Ljava/lang/String;");
    jfieldID iField = env->GetFieldID(cls, "i", "I");
    jfieldID cField = env->GetFieldID(cls, "c", "C");
    jfieldID bField = env->GetFieldID(cls, "b", "Z");
    jfieldID lField = env->GetFieldID(cls, "l", "J");
    jfieldID fField = env->GetFieldID(cls, "f", "F");
    jfieldID dField = env->GetFieldID(cls, "d", "D");

    // 修改成员变量的值
    env->SetObjectField(thiz, strField, env->NewStringUTF("改变之后的值。。。。"));
    env->SetIntField(thiz, iField, 42);
    env->SetCharField(thiz, cField, 'A');
    env->SetBooleanField(thiz, bField, JNI_TRUE);
    env->SetLongField(thiz, lField, 123L);
    env->SetFloatField(thiz, fField, 3.14f);
    env->SetDoubleField(thiz, dField, 2.718281828459045);
}
testData=new TestData("没改变的值",6,'a',true,1234567890L,3.14f,2.71828);
System.out.println(test2(testData));
testData.changeFields();
System.out.println(test2(testData));

反射修改静态变量sStr的值

#获取静态成员变量id 
GetStaticFieldID(class,"name","type")
#设置静态成员
SetStaticObjectField(class,id,value)
extern "C"
JNIEXPORT void JNICALL
Java_com_example_hellojni_TestData_changeStaticString(JNIEnv *env, jclass clazz, jstring str) {
    // TODO: implement changeStaticString()
    // 获取TestData类的Class对象
    jclass testDataClass = env->FindClass("com/example/hellojni/TestData");
    if (testDataClass == NULL) {
        return;
    }
    // 获取静态字段sStr的FieldID
    jfieldID sStrFieldID = env->GetStaticFieldID(testDataClass, "sStr", "Ljava/lang/String;");
    
    // 设置静态字段sStr的值
    env->SetStaticObjectField(testDataClass, sStrFieldID, str);
}
System.out.println(testData.getstring());
testData.changeStaticString("静态成员变量改变之后的值");
System.out.println(testData.getstring());