您的位置:首页 > 移动开发 > Android开发

Android NDK使用之--用pthread实现多线程

2015-12-16 21:23 537 查看
Android系统本身包括Java和Linux内核;因此在Android应用中实现多线程就可以是基于Java上的和基于Linux上的;今天本文介绍的就是Android利用Linux下的pthread来实现多线程;大概思路如下:

我们将异步任务需要实现的方法在Java中定义,但是运行异步任务的线程交给pthread实现;

因此首先设计一个接口,作为异步任务的业务接口:

//异步任务业务接口
public interface LocalRunnable {
public void run();
}


定义本地方法

/**
*
* @author 徐晔 线程池
*/
public class ThreadPool {
static {
System.loadLibrary("threadpool");
}
/** 初始化本地线程池 */
public native void init();
/** 本地线程中执行任务 */
public native int run(LocalRunnable runnable);
/**释放资源*/
public native void recycle();
}


通过本地方法类生成的.h文件如下:

com_localThread_ThreadPool.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
//实现pthread需要包括的接口
#include <unistd.h>
#include <pthread.h>
/* Header for class com_localThread_ThreadPool */

#ifndef _Included_com_localThread_ThreadPool
#define _Included_com_localThread_ThreadPool
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     com_localThread_ThreadPool
* Method:    init
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_localThread_ThreadPool_init(JNIEnv *, jobject);

/*
* Class:     com_localThread_ThreadPool
* Method:    run
* Signature: (Lcom/localThread/LocalRunnable;)I
*/
JNIEXPORT jint JNICALL Java_com_localThread_ThreadPool_run(JNIEnv *, jobject,
jobject);

/*
* Class:     com_localThread_ThreadPool
* Method:    recycle
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_localThread_ThreadPool_recycle(JNIEnv *,
jobject);

#ifdef __cplusplus
}
#endif
#endif


具体的实现代码如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "com_localThread_ThreadPool.h"
/* Header for class com_localThread_ThreadPool */

static JavaVM *jvm = NULL;
static jobject jobj = NULL;
static jmethodID mid = NULL;
static int flag = -1;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
//在加载库时执行
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
jvm = vm;
return JNI_VERSION_1_6;
}
//在卸载库时执行
void JNI_OnUnLoad(JavaVM *vm, void *reserved) {
jvm = NULL;
}
//pthread中执行的函数
void *nativeWork(void *args) {
JNIEnv *env = NULL;
//将本地线程连接到虚拟机上,这样本地线程才对虚拟机可见并且可以访问到虚拟机所在进程的资源
if (0 == jvm->AttachCurrentThread(&env, NULL)) {
while (flag == 0) {
if (jobj == NULL) {
//进入等待
pthread_cond_wait(&cond, &mutex);
} else {
//执行方法
env->CallVoidMethod(jobj, mid);
env->DeleteGlobalRef(jobj);
jobj = NULL;
}
}
jvm->DetachCurrentThread();
}
return (void *) 1;
}

/*
* Class:     com_localThread_ThreadPool
* Method:    init
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_localThread_ThreadPool_init(JNIEnv * env,
jobject obj) {
if (NULL == mid) {
//缓存方法
jclass cls = env->FindClass("com/localThread/LocalRunnable");
mid = env->GetMethodID(cls, "run", "()V");
if (mid == NULL) {
return;
}
flag = 0;
pthread_t thread;
//创建新线程
pthread_create(&thread, NULL, nativeWork, NULL);
}
}

/*
* Class:     com_localThread_ThreadPool
* Method:    run
* Signature: (Lcom/localThread/LocalRunnable;)I
*/
JNIEXPORT jint JNICALL Java_com_localThread_ThreadPool_run(JNIEnv * env,
jobject obj, jobject callback) {
//设置参数,唤醒等待的线程
flag=0;
jobj = env->NewGlobalRef(callback);
return pthread_cond_signal(&cond);
}

/*
* Class:     com_localThread_ThreadPool
* Method:    recycle
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_localThread_ThreadPool_recycle(JNIEnv * env,
jobject obj) {
//释放资源
flag = -1;
env->DeleteGlobalRef(jobj);
}


Java层对本地线程类的一个封装:

public class ThreadPoolRun {

/** 利用阻塞队列保存任务 */
private static LinkedBlockingDeque<BaseLocalRunnable> runnables = new LinkedBlockingDeque<BaseLocalRunnable>();
private BaseLocalRunnable lr = null;
public static ThreadPoolRun instance = new ThreadPoolRun();
private ThreadPool pool = null;
boolean runflag = false;

private ThreadPoolRun() {
pool = new ThreadPool();
pool.init();
}

/** 添加任务 */
public void addTask(BaseLocalRunnable runnable) {
runnables.addLast(runnable);
}

/** 取出任务 */
private BaseLocalRunnable getTask() {
try {
return runnables.removeFirst();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

public void runTask() {
synchronized (pool) {
lr = getTask();
if (lr != null && !runflag) {
runflag = true;
lr.before(lr.taskid);
pool.run(lr);
}
}

}
//当每次执行完成上一个任务后,设置标示,运行下一个任务
public void runend() {
runflag = false;
runTask();
}
}


实现基本任务类:

public abstract class BaseLocalRunnable implements LocalRunnable, MainRunnable {

private Handler mainHandler;
private MainRunnable mainRunnable;
int taskid;

public BaseLocalRunnable(Handler mainHandler, MainRunnable mainRunnable) {
this.mainHandler = mainHandler;
this.mainRunnable = mainRunnable;
}

@Override
public final void run() {
onfinished(dobackground(), taskid);
}

public final void execute(int taskid) {
ThreadPoolRun.instance.addTask(this);
this.taskid = taskid;
if (!ThreadPoolRun.instance.runflag) {
ThreadPoolRun.instance.runTask();
}

}

public abstract Object dobackground();

@Override
public final void onfinished(final Object object, final int raskid) {
mainHandler.post(new Runnable() {
@Override
public void run() {
if (mainRunnable != null) {
mainRunnable.onfinished(object, raskid);
}
// 读取下一个信息
ThreadPoolRun.instance.runend();
}
});

}

@Override
public final void before(int id) {
if (mainRunnable != null) {
mainRunnable.before(id);
}
}

}


主类需要实现的接口:

public interface MainRunnable {

public void before(int id);

public void onfinished(Object object, int raskid);

}


测试代码:

public class Task extends BaseLocalRunnable {

public Task(Handler mainHandler, MainRunnable mainRunnable) {
super(mainHandler, mainRunnable);
}

@Override
public Object dobackground() {
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
return "执行完成";
}

}

public class TestActivity extends Activity implements MainRunnable {

private TextView text;
private Button am_button;
private Handler mainHandler = null;
private Task task;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainHandler = new Handler(getMainLooper());
text = (TextView) findViewById(R.id.text);
am_button = (Button) findViewById(R.id.am_button);
am_button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
task = new Task(mainHandler, TestActivity.this);
task.execute(0);
}
});

}

@Override
public void before(int id) {
Log.v("任务", id + "开启");
}

@Override
public void onfinished(Object object, int taskid) {
Log.v("结果", "结束" + object.toString());
}
}


运行结果如下:我连续点击了几次按钮,出现的结果是一次一次执行

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: