- 浏览: 2196618 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1240)
- mac/IOS (287)
- flutter (1)
- J2EE (115)
- android基础知识 (582)
- android中级知识 (55)
- android组件(Widget)开发 (18)
- android 错误 (21)
- javascript (18)
- linux (70)
- 树莓派 (18)
- gwt/gxt (1)
- 工具(IDE)/包(jar) (18)
- web前端 (17)
- java 算法 (8)
- 其它 (5)
- chrome (7)
- 数据库 (8)
- 经济/金融 (0)
- english (2)
- HTML5 (7)
- 网络安全 (14)
- 设计欣赏/设计窗 (8)
- 汇编/C (8)
- 工具类 (4)
- 游戏 (5)
- 开发频道 (5)
- Android OpenGL (1)
- 科学 (4)
- 运维 (0)
- 好东西 (6)
- 美食 (1)
最新评论
-
liangzai_cool:
请教一下,文中,shell、C、Python三种方式控制led ...
树莓派 - MAX7219 -
jiazimo:
...
Kafka源码分析-序列5 -Producer -RecordAccumulator队列分析 -
hp321:
Windows该命令是不是需要安装什么软件才可以?我试过不行( ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
hp321:
Chenzh_758 写道其实直接用一下代码就可以解决了:JP ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
huanghonhpeng:
大哥你真强什么都会,研究研究。。。。小弟在这里学到了很多知识。 ...
android 浏览器
1、主要流程
1、 String 字符串传输
2、 自定义对象的传输
2设计实现
1、 界面设计如下:
代码不在这贴出了,有需要的兄弟直接到文章结束部分下载。
2、 关键代码说明
Transmission.java
MainActivity.java
TransmissionPerson.c
TransmissionString.c
1、 String 字符串传输
- a) 上层定义一个native的方法,需要一个String 参数 ,返回一个String
- b) JNI对应上层的方法,打印出上层传输下来的String数据,并返回处理String数据
- c) 上层 收到 native 方法 返回的 值,在UI中显示出来
2、 自定义对象的传输
- a) 自定义一个对象Person
- b) 上层定义一个native方法,参数Person,返回值Person
- c) JNI接收对象,打印出相关信息数据
- d) JNI 修改Person 对象数据,并返回到上层
- e) 上层接收到数据后 在UI显示出来
2设计实现
1、 界面设计如下:
代码不在这贴出了,有需要的兄弟直接到文章结束部分下载。
2、 关键代码说明
Transmission.java
package com.duicky; /** * * <p> * Title: aa.java * </p> * <p> * E-Mail: 176291935@qq.com * </p> * <p> * QQ: 176291935 * </p> * <p> * Http: iaiai.iteye.com * </p> * <p> * Create time: 2011-9-19 * </p> * * @author 丸子 * @version 0.0.1 */ public class Transmission { private static final String libSoName = "NDK_07"; public native String transferString(String mStrMSG); public native Object transferPerson(Person mPerson); /** * 载入JNI生成的so库文件 */ static { System.loadLibrary(libSoName); } }
MainActivity.java
package com.duicky; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; /** * * <p> * Title: MainActivity.java * </p> * <p> * E-Mail: 176291935@qq.com * </p> * <p> * QQ: 176291935 * </p> * <p> * Http: iaiai.iteye.com * </p> * <p> * Create time: 2011-9-19 * </p> * * @author 丸子 * @version 0.0.1 */ public class MainActivity extends Activity { //也就是你mk配置文件中的 LOCAL_MODULE := NDK_06 private Context mContext = null; private Transmission mTransmission = null; private Button btnString = null; private Button btnPerson = null; private TextView tvString = null; private TextView tvPerson = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mContext = this; mTransmission = new Transmission(); initViews(); } /** * 初始化控件 */ private void initViews() { btnString = (Button) findViewById(R.id.btn_string); btnPerson = (Button) findViewById(R.id.btn_person); tvString = (TextView) findViewById(R.id.tv_string); tvPerson = (TextView) findViewById(R.id.tv_person); btnString.setOnClickListener(new MyOnClickListener()); btnPerson.setOnClickListener(new MyOnClickListener()); } private void transferString() { String mStrMSg = mTransmission.transferString(" This Message come from Java "); LogUtils.printWithSystemOut(mStrMSg); tvString.setText(mStrMSg); } private void transferPerson() { Person mPerson = new Person(); mPerson.setAge(10); mPerson.setName("duicky"); Person mPerson1 = (Person)mTransmission.transferPerson(mPerson); if(mPerson1 == null) { LogUtils.printWithSystemOut("error"); tvPerson.setText("传递出现错误,请重试"); return; } LogUtils.printWithSystemOut(mPerson1.toString()); tvPerson.setText("Java --- > "+mPerson1.toString()); } class MyOnClickListener implements OnClickListener{ @Override public void onClick(View v) { switch(v.getId()) { case R.id.btn_string: transferString(); break; case R.id.btn_person: transferPerson(); break; } } } }
TransmissionPerson.c
#include <string.h> #include <jni.h> #include <android/log.h> extern JNIEnv* jniEnv; jclass Person; jobject mPerson; jmethodID getName; jmethodID setName; jmethodID getAge; jmethodID setAge; jmethodID toString; int InitPerson(); void ToString(); void GetName(); void GetAge(); void SetName(); void SetAge(); //---------------------------------------------------------------- //---------------------------------------------------------------- //---------------------------------------------------------------- jobject Java_com_duicky_Transmission_transferPerson( JNIEnv* env,jobject thiz,jobject person ) { if(jniEnv == NULL) { jniEnv = env; } if (Person == NULL || getName == NULL || setName == NULL || getAge == NULL || setAge == NULL || toString == NULL) { if (1 != InitPerson()) { return NULL; } } mPerson = person; if(mPerson == NULL) { return NULL; } GetName(); GetAge(); ToString(); __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Begin Modify mPerson .... " ); SetName(); SetAge(); ToString(); return mPerson; } //---------------------------------------------------------------- //---------------------------------------------------------------- //---------------------------------------------------------------- /** * 初始化 类、方法 */ int InitPerson() { __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin " ); if(jniEnv == NULL) { return 0; } if(Person == NULL) { Person = (*jniEnv)->FindClass(jniEnv,"com/duicky/Person"); if(Person == NULL){ return -1; } __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin 2 ok" ); } if (getName == NULL) { getName = (*jniEnv)->GetMethodID(jniEnv, Person, "getName","()Ljava/lang/String;"); if (getName == NULL) { (*jniEnv)->DeleteLocalRef(jniEnv, Person); return -2; } __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin 4 ok" ); } if (setName == NULL) { setName = (*jniEnv)->GetMethodID(jniEnv, Person, "setName","(Ljava/lang/String;)V"); if (setName == NULL) { (*jniEnv)->DeleteLocalRef(jniEnv, Person); (*jniEnv)->DeleteLocalRef(jniEnv, getName); return -2; } __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin 4 ok" ); } if (getAge == NULL) { getAge = (*jniEnv)->GetMethodID(jniEnv, Person, "getAge","()I"); if (getAge == NULL) { (*jniEnv)->DeleteLocalRef(jniEnv, Person); (*jniEnv)->DeleteLocalRef(jniEnv, getName); (*jniEnv)->DeleteLocalRef(jniEnv, setName); return -2; } __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin 4 ok" ); } if (setAge == NULL) { setAge = (*jniEnv)->GetMethodID(jniEnv, Person, "setAge","(I)V"); if (setAge == NULL) { (*jniEnv)->DeleteLocalRef(jniEnv, Person); (*jniEnv)->DeleteLocalRef(jniEnv, getName); (*jniEnv)->DeleteLocalRef(jniEnv, setName); (*jniEnv)->DeleteLocalRef(jniEnv, getAge); return -2; } __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin 4 ok" ); } if (toString == NULL) { toString = (*jniEnv)->GetMethodID(jniEnv, Person, "toString","()Ljava/lang/String;"); if (toString == NULL) { (*jniEnv)->DeleteLocalRef(jniEnv, Person); (*jniEnv)->DeleteLocalRef(jniEnv, getName); (*jniEnv)->DeleteLocalRef(jniEnv, setName); (*jniEnv)->DeleteLocalRef(jniEnv, getAge); (*jniEnv)->DeleteLocalRef(jniEnv, setAge); return -2; } __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin 4 ok" ); } __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson End" ); return 1; } /** * GetName 对应Person的getName方法 */ void GetName() { if(Person == NULL || getName == NULL) { if(1 != InitPerson()){ return; } } jstring jstr = NULL; char* cstr = NULL; //调用方法 jstr = (*jniEnv)->CallObjectMethod(jniEnv, mPerson, getName); cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0); __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "getName ---- > %s",cstr ); //释放资源 (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr); (*jniEnv)->DeleteLocalRef(jniEnv, jstr); } /** * GetAge 对应Person的getName方法 */ void GetAge() { if(Person == NULL || getName == NULL) { if(1 != InitPerson()){ return; } } //调用方法 jint age = (*jniEnv)->CallIntMethod(jniEnv, mPerson, getAge); __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "getAge ---- > %d",age ); } /** * SetName 对应Person的setName方法 */ void SetName() { if(Person == NULL || setName == NULL) { if(1 != InitPerson()){ return; } } jstring jstr = (*jniEnv)->NewStringUTF(jniEnv, "Modify Name"); //调用方法 (*jniEnv)->CallVoidMethod(jniEnv, mPerson, setName,jstr); (*jniEnv)->DeleteLocalRef(jniEnv, jstr); } int age = 20; /** * SetAge 对应Person的setAge方法 */ void SetAge() { if(Person == NULL || setAge == NULL) { if(1 != InitPerson()){ return; } } //调用方法 (*jniEnv)->CallVoidMethod(jniEnv, mPerson, setAge,age++); } /** * ToString 对应 Person 的 toString 方法 , 打印出相关信息 */ void ToString() { if(Person == NULL || toString == NULL) { if(1 != InitPerson()){ return; } } jstring jstr = NULL; char* cstr = NULL; //调用方法 jstr = (*jniEnv)->CallObjectMethod(jniEnv, mPerson, toString); cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0); __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "C JNI toString ---- > %s",cstr ); (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr); (*jniEnv)->DeleteLocalRef(jniEnv, jstr); }
TransmissionString.c
#include <string.h> #include <jni.h> #include <android/log.h> JNIEnv* jniEnv; jstring Java_com_duicky_Transmission_transferString( JNIEnv* env,jobject thiz,jstring msg ) { if(jniEnv == NULL) { jniEnv = env; } char data[128]; memset(data, 0, sizeof(data)); char *c_msg = NULL; c_msg = (char *)(*jniEnv)->GetStringUTFChars(jniEnv, msg, 0); __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "C JNI ---- > %s",c_msg); return (*jniEnv)->NewStringUTF(jniEnv, "This is send by C JNI"); }
发表评论
-
jni未释放资源问题。Failed adding to JNI local ref table (has 512 entries)
2016-02-01 14:51 979Native Code 本身的内存泄漏 JNI 编程首先是一 ... -
android ApkPlug使用
2015-12-09 15:14 712直接下载附件吧, 有两个是官方的demo包,还有一个是他们技术 ... -
dynamic-load-apk-Apk动态加载框架使用初体验
2015-12-03 10:40 794因为想要将本网站上的开源代码直接做成一个能显示效果的app,决 ... -
Android动态加载进阶 代理Activity模式
2015-11-30 17:20 880技术背景 简单模式中 ... -
Android NDK rb5 文档之本地活动和应用程序
2015-11-24 22:34 811Native Activities and Applicati ... -
Android NDK rb5 文档之 native_activity.h 文件翻译
2015-11-24 22:30 1003/** * Copyright (C) 2010 The A ... -
Android新技术学习——阿里巴巴免Root无侵入AOP框架Dexposed
2015-11-21 13:49 1785引用阿里巴巴无线事业部最近开源的Android平台下的无侵入运 ... -
Android NDK开发之JNI基础知识
2015-11-21 13:05 1123JAVA层与JNI层数据类型的对应 下面是一个测试方法 pu ... -
ANDROID2.2 JNI 配置luajit2
2015-11-21 11:18 736去http://luajit.org/官网下载最新的版本 在 ... -
在Android平台上加载本地库的危险性[转]
2015-11-13 09:30 1586在2012年KeepSafe的创业初期,我们试图找到一种为An ... -
JNI: 能否用 GetFieldID()/GetStaticFieldID()取得enum变量的属性?
2015-11-06 11:52 1834没有问题的,jni下面一样可以动态获取的 仅供参考! VOI ... -
ndk-stack定位不出崩溃代码行的问题
2015-10-30 08:51 1246NDK开发包中自带的NDK-STACK工具是可以查看崩溃栈信息 ... -
Android.mk文件详解
2015-10-27 09:23 1831Android.mk是Android提供的 ... -
NDK在增加断点时跳不进去,不管用的解决办法
2015-10-26 10:09 1103先看下面的错,如果报的不是这个那就不是我这个问题,那就不用再看 ... -
插件化的基石 -- apk动态加载
2015-09-25 09:13 967Android动态加载技术在蘑菇街的第一次实践,还是在14年的 ... -
warning:deprecated conversion from string constant to 'char *' 解决方案
2015-09-25 09:01 1847char* createClass(){ ret ... -
jni内存释放
2015-09-24 12:03 3671调用GetStringUTFChars,GetDoubleAr ... -
如何不要让ndk-build自动删除.so
2015-08-04 15:33 1157在用ndk-build的时候突然发现在编译完成之后会自动删除a ... -
超简单的NDK单步调试方法
2015-08-03 21:19 599最近为了性能需求,开始搞JNI,白手起搞真心不容易。中间差点崩 ... -
JNI调用java中的类方法和静态方法
2015-08-03 16:46 2754在JNI调用中,肯定会涉及到本地方法操作Java类中数据和方法 ...
相关推荐
Android NDK,全称为Native Development Kit,是Google提供的一款用于Android平台的C和C++开发工具集。...通过“android-ndk-r26b-windows.zip”,Windows用户可以方便地获取并开始他们的原生代码开发之旅。
这个“android-ndk-r25b-linux.zip”文件是NDK的一个特定版本,即r25b,专为Linux操作系统设计。在Android应用开发中,NDK扮演着至关重要的角色,它允许开发者使用原生代码(如C和C++)来编写部分应用,以提高性能、...
这个压缩包“android-ndk-r25b-windows.zip”包含了NDK的第25个版本,专为Windows操作系统设计。NDK的主要功能是让开发者能够在Android应用中使用原生代码,例如C、C++,以实现高性能计算或利用硬件加速等功能。 **...
这个"android-ndk-r23b-windows.zip"压缩包包含了NDK的第23个版本,专为Windows操作系统设计。NDK是Android应用开发中的一个重要组成部分,它允许开发者使用原生代码(如C、C++)来编写部分应用程序,从而利用底层的...
可用于安卓 qt开发 安卓NDK android-ndk-r12b-windows-x86_64
在本案例中,我们关注的是"android-ndk-r26b-darwin.zip",这是一个专为macOS系统设计的NDK版本。 **Android NDK的主要功能和用途** 1. **性能优化**:对于计算密集型或图形密集型的应用,如游戏和复杂的科学计算...
echo 'export PATH=$PATH:/opt/android/ndk/android-ndk-r19c' | sudo tee -a ~/.bashrc source ~/.bashrc ``` 现在,NDK已准备就绪。接下来,我们需要安装QT 5.13。访问QT官方网站(https://www.qt.io/download)...
标题中的“android-ndk-r18b-windows-x86_64.zip”表明这是一个适用于Windows 64位系统的Android NDK版本,具体为R18B更新。 在Android应用开发中,NDK的主要用途包括: 1. **性能优化**:对于计算密集型或图形...
4. **工具链**:NDK包含了一系列编译、链接和其他工具,如arm-linux-androideabi-gcc(此版本的GCC)和clang,用于构建和优化针对不同Android架构的本地代码。 5. **预编译库**:NDK附带了一些预编译的库,如...
这个“android-ndk-r23b-linux.zip”文件是NDK的一个特定版本,即r23b,专为Linux操作系统设计。在Android应用开发中,NDK扮演着至关重要的角色,它允许开发者使用原生代码(如C和C++)来编写部分应用,以提升性能或...
对于64位Windows用户来说,"android-ndk-r20b-windows-x86_64.zip"是一个关键资源,它意味着可以直接在Windows环境中搭建本地开发环境,无需担心系统架构问题。解压后的文件包括了所有必要的工具和库,如编译器、...
android-ndk-r18b-linux-x86_64.zip https://dl.google.com/android/repository/android-ndk-r18b-linux-x86_64.zip
android-ndk-r10e-windows-x86_64.exe
《深入理解Android NDK:基于android-ndk-r20-linux-x86_64.zip的探讨》 Android NDK,全称为Native Development Kit,是Google为开发者提供的一套工具集合,它允许开发者使用C和C++语言进行Android应用程序的开发...
标题中的"android-ndk-r10e-linux-x86_64"表明这是一个特定版本的NDK,即版本号为R10e,针对Linux 64位系统的版本。 **NDK的基本概念与功能:** 1. **本地库开发:**NDK允许开发者使用C/C++编写部分或全部应用代码...
"android-ndk-r16b-windows-x86_64.zip" 是NDK的第16个版本,特别为Windows 64位操作系统设计。 在Android应用开发中,通常我们使用Java或Kotlin编写大部分代码,但由于这些语言运行在Dalvik或ART虚拟机上,它们的...
`android-ndk-r25b-darwin.zip` 是针对macOS系统的NDK版本,版本号为r25b,包含了一系列用于构建、编译和调试原生代码的工具。 在Android应用开发中,NDK的主要作用和知识点包括: 1. **JNI (Java Native ...
这个“android-ndk-r26b-linux.zip”文件是NDK的一个特定版本——R26B,特别为Linux操作系统设计。 NDK的主要功能和知识点包括: 1. **原生库支持**:NDK允许开发者创建原生库,这些库可以直接在设备的CPU上运行,...
《Android NDK R9:深入理解与应用》 Android NDK(Native Development Kit)是Google为Android平台提供的一套工具,允许开发者使用C/C++语言编写应用程序,从而利用原生代码的高性能。本文将深入探讨Android NDK ...