一:JNI多线程
1,android中的进程和线程
java虚拟机叫jvm,一个java程序可能有多个jvm,android虚拟机Dalvik vm,现在转化为ART VM(android run time),一个android的APP就是一个虚拟机,与java不同,java可以是多进程的,但是android APP只有一个进程(android 系统可以有多个进程),
2.POSIX标准UNIX族类系统(可移植操作系统接口)线程库pthread
3.android libc,bionic为pthreads提供了内置的支持,所以没有必要额外的链接(-lpthreads)。它并没有实现完整的POSIX线程功能,并且不支持读/写锁,pthread_cancel(),互斥进程共享和条件变量以及其他更高级的功能。
TLS,线程本地存储,限制为59 个可用于应用程序的pthread_key_t插槽,低于posix最低的128个
看下MainActivity类
package com.example.acer.test_18_02_26;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("张欣念我一生一世"+Thread.currentThread().getName().toString());
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
public void temp(){
System.out.println("张欣念我一生一世"+Thread.currentThread().getName().toString());
}
}
native-lib文件
#include <jni.h>
#include <string>
//#include <pthread.h>在android中不需要引入
//获取存放虚拟机的对象,把当前的进程拿下来
JavaVM *j_vm;
//定义一个新线程的对象,
pthread_t new_thread;
//声明一个线程调用的方法
void *run(void *);
//回调java的方法的id
jmethodID callBack;
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_example_acer_test_118_102_126_MainActivity_stringFromJNI(
JNIEnv *env,
jobject jobj) {
//一个结构体变量指针env对应当前的一个线程,获取当前的jvm;把虚拟机与env进行绑定
//参数为指针变量的指针
env->GetJavaVM(&j_vm);
// 获得实例对应的class类
jclass cls = env->GetObjectClass(jobj);
//V要大写
callBack = env->GetMethodID(cls, "temp", "()V");
//将当前的对象定义为全局的引用
jobject obj = env->NewGlobalRef(jobj);
//开启新的线程
//四个参数:1,线程id的地址;
// 2,表明我们的运行环境(是android还是其他的什么);NULL表示当前运行环境
//3,新县城调用的方法;4,被调用的方法需要的参数
pthread_create(&new_thread, NULL, run, obj);
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
void *run(void *obj) {
//记录new_env的状态值
int status;
//创建一个新的环境变量(env是先前的环境)
JNIEnv* new_env;//新的环境变量,和新的线程绑定
//标记线程的状态
bool isAttach = false;
//验证new_env是不是一个有效的指针
//如果不是有效的,将指针绑定到当前的虚拟机上,如果已经绑定,则忽略
status=j_vm->GetEnv((void **) &new_env, JNI_VERSION_1_6);
if(status<0){
//将当前线程依附到当前的虚拟机上
status=j_vm->AttachCurrentThread(&new_env,NULL);
if(status<0){
//依附失败
return NULL;
}
isAttach=true;
}
//执行当前线程需要做的事情
new_env->CallVoidMethod((jobject) obj, callBack);
if(isAttach){
//解除线程的绑定,成对出现
j_vm->DetachCurrentThread();
return NULL;
}
}
看下运行结果
02-26 19:51:17.293 3434-3434/com.example.acer.test_18_02_26 I/System.out: 张欣念我一生一世main
02-26 19:51:17.301 3434-3448/com.example.acer.test_18_02_26 I/System.out: 张欣念我一生一世Thread-176
说明MainActivity里的temp方法调用了,两个线程不是同一个线程
二:JNI_OnLoad我也没搞明白,暂时不更新了