Android NDK使用之--用pthread实现多线程
2015-12-16 21:23
537 查看
Android系统本身包括Java和Linux内核;因此在Android应用中实现多线程就可以是基于Java上的和基于Linux上的;今天本文介绍的就是Android利用Linux下的pthread来实现多线程;大概思路如下:
我们将异步任务需要实现的方法在Java中定义,但是运行异步任务的线程交给pthread实现;
因此首先设计一个接口,作为异步任务的业务接口:
定义本地方法
通过本地方法类生成的.h文件如下:
具体的实现代码如下:
Java层对本地线程类的一个封装:
实现基本任务类:
主类需要实现的接口:
测试代码:
运行结果如下:我连续点击了几次按钮,出现的结果是一次一次执行
我们将异步任务需要实现的方法在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()); } }
运行结果如下:我连续点击了几次按钮,出现的结果是一次一次执行
相关文章推荐
- 深入理解Android 编译系统
- android studio 中去除应用标题栏
- Android下手动挂载分区
- Android学习之Spinner
- android之文件存储路径
- Android Studio for Ubuntu 14.04 无法输入中文解决办法
- SpannableString中的LinkMovementMethod和ClickableSpan的实现安卓可点击有颜色文字使用
- android 使用String.format("%.2f",67.876)自已定义语言(俄语、西班牙语)会把小数点变为逗号
- android按两次返回键退出程序
- Android TextView查看更多
- Log.d and Log.v for Android
- Android判断ListView滚动到最顶部第0条item完全完整可见及最底部最后一条item完全完整可见
- Android中通过typeface设置字体
- Android 控件之ImageViewSwitcher图片切换控件
- android:versionCode 跟 android:versionName
- android开发中scrollview添加自定义view的滑动显示问题
- Android读书笔记之Fragment入门
- android判断当前系统的语言
- Android倒计时器——CountDownTimer
- Android倒计时器——CountDownTimer