zoukankan      html  css  js  c++  java
  • 解决JNI native 线程不能正常退出的问题

    本人刚涉足学习C++ 安卓  java,遇到这个棘手的问题,多谢博客园作者lknlfy 看了你的博客解决了这个问题,此文转发, 方便日后学习

    以下内容转自lknlfy作者博客  传送门:http://www.cnblogs.com/lknlfy/archive/2012/03/16/2400786.html

    ====================================================分界线===============================================================================

    一、概述

          JNI编程和Linux上的C/C++编程还是挺相似的,每次java调用JNI中的函数时都会传入有关JVM的一些参数(如JNIEnv,jobject),每次JNI回调java中的方法时都要通过JVM的有关参数来实现,当在JNI中涉及到多线程的话还是有一些不一样的地方,就是要在子线程函数里使用AttachCurrentThread()和DetachCurrentThread()这两个函数,在这两个函数之间加入回调java方法所需要的代码。

    二、要求

         掌握JNI多线程编程的方法。

    三、实现

         新建工程MyThread,修改main.xml文件,在里面只有一个Button,如下:

    复制代码
     1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3 android:layout_width="fill_parent"
    4 android:layout_height="fill_parent"
    5 android:orientation="vertical" >
    6
    7 <Button
    8 android:id="@+id/button"
    9 android:layout_width="fill_parent"
    10 android:layout_height="wrap_content"
    11 android:text="启动JNI线程"
    12 />
    13
    14 </LinearLayout>
    复制代码

    修改MyThreadActivity.java文件,实现按钮的监听,在里面调用JNI中的函数来启动JNI中的线程,比较简单,如下:

    复制代码
     1 package com.nan.thread;
    2
    3 import android.app.Activity;
    4 import android.os.Bundle;
    5 import android.util.Log;
    6 import android.view.View;
    7 import android.widget.Button;
    8
    9 public class MyThreadActivity extends Activity
    10 {
    11 private Button mButton = null;
    12
    13 /** Called when the activity is first created. */
    14 @Override
    15 public void onCreate(Bundle savedInstanceState)
    16 {
    17 super.onCreate(savedInstanceState);
    18 setContentView(R.layout.main);
    19
    20 mButton = (Button)this.findViewById(R.id.button);
    21 //按钮监听
    22 mButton.setOnClickListener(new View.OnClickListener()
    23 {
    24
    25 @Override
    26 public void onClick(View v)
    27 {
    28 // TODO Auto-generated method stub
    29 //调用JNI中的函数来启动JNI中的线程
    30 mainThread();
    31
    32 }
    33 });
    34 //初始化JNI环境
    35 setJNIEnv();
    36 }
    37
    38 //由JNI中的线程回调
    39 private static void fromJNI(int i)
    40 {
    41 Log.v("Java------>", ""+i);
    42 }
    43
    44 //本地方法
    45 private native void mainThread();
    46 private native void setJNIEnv();
    47
    48 static
    49 {
    50 //加载动态库
    51 System.loadLibrary("JNIThreads");
    52 }
    53
    54 }
    复制代码

    编写JNI_Thread.c文件,在mainThread()函数里启动5个子线程,在子线程函数里回调java中的静态方法fromJNI()来输出当前子线程是第几个被启动的线程。完整的内容如下:

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

    最后,编写Android.mk文件:

    复制代码
     1 LOCAL_PATH := $(call my-dir)
    2
    3 include $(CLEAR_VARS)
    4
    5 LOCAL_MODULE := JNIThreads
    6 LOCAL_SRC_FILES := JNI_Threads.c
    7
    8 LOCAL_LDLIBS := -llog
    9
    10 include $(BUILD_SHARED_LIBRARY)
    复制代码

    使用ndk-build成功编译出动态库后,运行该程序:

    并点击2下按钮,LogCat输出如下:

       

    ====================================================分界线===============================================================================

    Mark  Mark!!!!

  • 相关阅读:
    什么是云安全
    VMWare vForum 2013看点
    循环和数据的操作命令
    程序交互
    数据类型
    基础变量
    模块和包
    ['hello', 'sb']正则表达式
    os模块
    内置函数
  • 原文地址:https://www.cnblogs.com/Carlsblog/p/9438016.html
Copyright © 2011-2022 走看看