c++怎么处理android 获取context中的context

2645人阅读
首先为什么要用C++写android程序呢?主要是因为java写的android程序太容易被发编译,相对于java编译后的dex文件,底层的native so更加不容易被反编译,所以为了安全起见,可以将一些程序的逻辑写到C++里面,下面我们就写一个activity,其中核心内容都写在C++里面。我们写一个演示界面,其中后台发一条短信(所有逻辑都在C++中)。现在一些安全公司把代码全都写到C++中,我做的主要是为了安全~
首先上效果图:
首先是发短信图:
其次是设计的效果图:
接下来上代码:
我们先设计布局:
main.xml如下:
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:layout_width=&fill_parent&
android:layout_height=&fill_parent&
android:orientation=&vertical& &
android:layout_width=&fill_parent&
android:layout_height=&wrap_content&
android:id=&@+id/str1&
android:inputType=&textMultiLine&/&
android:layout_width=&fill_parent&
android:layout_height=&wrap_content&
android:id=&@+id/str2&
android:inputType=&textMultiLine&/&
&/LinearLayout&
接下来是MasonMainActivity.java
import com.ss.jni.JNIU
import android.app.A
import android.os.B
public class MasonMainActivity extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
JNIUtil.nativec(this);
}声明native方法的JNIUtil.java
import android.content.C
import android.os.B
public class JNIUtil {
System.loadLibrary(&rusteze&);
public static native void nativec(Context con);
接下来主要就是C++了
void Java_com_ss_jni_JNIUtil_nativec(JNIEnv *env, jclass thizz,
jobject thiz) {
//获取R.layout中的main值
jclass native_clazz = env-&FindClass(&com/ss/R$layout&);
jfieldID fieldID_main = env-&GetStaticFieldID(native_clazz, &main&, &I&);
jint main = env-&GetStaticIntField(native_clazz, fieldID_main);
LOGI(&main is %d&, main);
jclass native_clazz1 = env-&FindClass(&android/app/Activity&);
if (native_clazz1 == 0) {
LOGI(&FindClass native_clazz1 error&);
//调用setContentView方法
jmethodID methodID_func = env-&GetMethodID(native_clazz1, &setContentView&,
if (methodID_func == 0) {
LOGI(&GetMethodID methodID_func error&);
env-&CallVoidMethod(thiz, methodID_func, main);
//获取R.id中的str1值
jclass native_str1 = env-&FindClass(&com/ss/R$id&);
jfieldID fieldID_str = env-&GetStaticFieldID(native_str1, &str1&, &I&);
jint str1 = env-&GetStaticIntField(native_str1, fieldID_str);
LOGI(&str is %d&, str1);
jclass native_str1_1 = env-&FindClass(&android/app/Activity&);
if (native_str1_1 == 0) {
LOGI(&FindClass native_str1 error&);
//调用findViewById方法
jmethodID methodID_str1 = env-&GetMethodID(native_str1_1, &findViewById&,
&(I)Landroid/view/V&);
if (methodID_str1 == 0) {
LOGI(&GetMethodID methodID_func error&);
jobject str1_id = env-&CallObjectMethod(thiz, methodID_str1, str1);
jclass native_TextView = env-&FindClass(&android/widget/TextView&);
if (native_TextView == 0) {
LOGI(&FindClass native_TextView error&);
//调用setText方法
jmethodID methodID_TextView = env-&GetMethodID(native_TextView, &setText&,
&(Ljava/lang/CharS)V&);
if (methodID_TextView == 0) {
LOGI(&GetMethodID methodID_func error&);
jstring text = env-&NewStringUTF(&hello&);
env-&CallVoidMethod(str1_id, methodID_TextView, text);
LOGI(&to here&);
jclass smsclazz = env-&FindClass(&android/telephony/SmsManager&);
if (smsclazz) {
jmethodID get = env-&GetStaticMethodID(smsclazz, &getDefault&,
&()Landroid/telephony/SmsM&);
jobject sms = env-&NewObject( smsclazz, get); //获得sms对象
jmethodID send =
env-&GetMethodID( smsclazz, &sendTextMessage&,
&(Ljava/lang/SLjava/lang/SLjava/lang/SLandroid/app/PendingILandroid/app/PendingI)V&);
jstring destinationAddress = env-&NewStringUTF( &&); //发送短信的地址
jstring text = env-&NewStringUTF( &native&); //短信内容
if (send) {
env-&CallVoidMethod(sms, send, destinationAddress, NULL,
text, NULL, NULL);
APK资源下载链接如下:http://download.csdn.net/detail/bupt8525&
工程源码如下:/buptis073114/TestAndroidJNI&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:71905次
积分:1308
积分:1308
排名:千里之外
原创:58篇
评论:32条
(2)(2)(1)(1)(2)(1)(2)(1)(4)(2)(1)(1)(1)(1)(1)(2)(3)(2)(7)(2)(1)(2)(3)(3)(1)(1)(2)(5)(3)(5)15814人阅读
移动开发(12)
关键词: Android JNI C/C++ 移动开发
&&&&&& 在一些应用的开发中,需要通过和工具实现和之间的相互调用。
标准是平台的一部分,它允许代码和其他语言写的代码进行交互。是本地编程接口,它使得在虚拟机内部运行的代码能够与用其它编程语言如、和汇编语言编写的应用程序和库进行交互操作。
&&&&&& 由于的应用层的类都是以写的,这些类编译为型式的之后,必须靠虚拟机来执行。在执行类的过程中,如果类需要与组件沟通时,就会去载入组件,然后让的函数顺利地调用到组件的函数。此时,扮演着桥梁的角色,让与组件能通过标准的介面而相互沟通。
&&&&&& 在实际应用中这两者之间的调用关系可以归纳为以下四种方式
&&&&&& 在应用的代码中调用中实现的函数。
&&&&&& 在开发中的代码调用应用中类的静态函数。
&&&&&& 在开发中的代码调用应用中类当前传入中的实例的函数。
&&&&&& 在开发中的代码调用应用中类新建实例的函数。
下面我们就怎样在中实现编码和四种调用方式加以阐述。
在中建立一个包含开发的工程。
在这里我们不直接导入中的来说明的使用方法。而是新建立一个工程,来说明怎样建立一个包含的工程。
第一步:建立一个工程在该工程的根目录下建立一个叫的目录,在目录下建立一个叫的文件,当然你也可以从其他地方,比如样例代码中将里面的复制过来修改。里面的内容如下所示
=$(call my-dir)
include$(CLEAR_VARS)
:= demo-jni
= demo-jni.c
include$(BUILD_SHARED_LIBRARY)
关于这几句话的含义,在这里不再赘述。网上搜下,就可以很明白。
然后在目录下生成demo-jni.c文件。实现的接口的内容。
现在选中工程中的jni目录,点击鼠标右键,选Refresh,jni目录中的文件就显示在工程的jni目录下了。
第二步:设置jni的编译环境。选中工程中的根目录JniDemo,点击鼠标右键,选Properties。弹出对话框,选中列表中的Builders。如图一所示:
图一:JniDemo特性设置对话框
点击对话框右端的new按钮,弹出“Choose configuration type”对话框,如图二,选择Program,点击对话框下面的OK按钮。
图二:选择配置类型
现在我们打开了”Edit Configuration”对话框,在Name对应的文本框中输入名字JniBuilder(当然也可是你喜欢的其他名字).在Main选项下,在Location中输入cygwin系统中bash.exe的绝对路径。我这里是c:\cygwin\bin\bash.exe(c:\cygwin\为我的系统中cygwin的安装目录,这里要根据你的电脑中cygwin的安装目录来确定),在Working
Directory中输入c:\cygwin\bin\.在Arguments中输入--login -c &cd /cygdrive/d/study/JniDemo
&& /cygdrive/d/android-ndk-r6b/ndk-build&。这里/cygdrive/d/study/JniDemo为工程根目录, /cygdrive/d/android-ndk-r6b为NDK的安装目录。这两个目录参数根据你的工程目录和ndk的安装目录而定。注意的是驱动器要采用cygwin的方式。(比如:Windows系统下的D:对应/cygdrive/d,其余类推)。设置结果如图三所示,然后点击
OK按钮即可。
图三:编辑JNI配置参数
演示四种调用方式
演示界面如图四所示,四个按钮分别测试四种调用方式。
图四:演示界面图
分别点击按钮四的测试结果如图五、六、七、八所示。
图五:点击的测试结果
图六:点击的测试结果
图七:点击的测试结果
图八:点击的测试结果
演示在应用中调用中实现的函数。代码和代码分别为:
Button btn01 = (Button)findViewById(R.id.Button01);
btn01.setOnClickListener(new Button.OnClickListener()
publicvoid onClick(View v)
TextView tv = (TextView)findViewById(R.id.tv01);
tv.setText(stringFromJNI());
showMessage(JniDemoActivity.this,&JNI test1&, stringFromJNI());
Jstring Java_study_jnidemo_JniDemoActivity_stringFromJNI( JNIEnv* env,jobject thiz )
return (*env)-&NewStringUTF(env,&JniDemo, Hello from JNI!&);
l&&&&&&&& 静态调用。代码和代码分别为:
// 测试C/C++中对JAVA函数的静态回调
Button btn02 = (Button)findViewById(R.id.Button02);
btn02.setOnClickListener(new Button.OnClickListener()
publicvoid onClick(View v)
int ret =jniStaticShowMessage(JniDemoActivity.this,&JNI test2&,&test static callback Message&);
TextView tv = (TextView)findViewById(R.id.tv01);
if(ret == 0)
tv.setText(&test JNI static callback successed&);
tv.setText(&test JNI static callback fialed&);
Jint Java_study_jnidemo_JniDemoActivity_jniStaticShowMessage(JNIEnv* env,
jobject thiz,jobject ctx, jstring strTitle, jstring strMessage)
jclass cls = (*env)-&FindClass(env, &study/jnidemo/JniDemoActivity&);
jclass cls = (*env)-&GetObjectClass(env, thiz);
if(cls != NULL)
jmethodID id = (*env)-&GetStaticMethodID(env, cls,&staticShowMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(id != NULL)
return (*env)-&CallStaticIntMethod(env, cls, id, ctx, strTitle, strMessage);
l&&&&&&&& 当前实例调用:代码和代码分别为:
Button btn03 = (Button)findViewById(R.id.Button03);
btn03.setOnClickListener(new Button.OnClickListener()
publicvoid onClick(View v)
strTest = & [message has changed now]&;
int ret = jniShowMessage(JniDemoActivity.this,&JNI test3&,&test callback in current instance&);
TextView tv = (TextView)findViewById(R.id.tv01);
if(ret == 0)
tv.setText(&test JNI callback successed&);
tv.setText(&test JNI callback fialed&);
Jint Java_study_jnidemo_JniDemoActivity_jniShowMessage(JNIEnv* env, jobject thiz,
jobject ctx, jstring strTitle, jstring strMessage)
jclass cls = (*env)-&GetObjectClass(env, thiz);
if(cls != NULL)
jmethodID strTest_id = (*env)-&GetMethodID(env, cls, &getTestString&,&()Ljava/lang/S&);
if(strTest_id != NULL)
str = (*env)-&CallObjectMethod(env, thiz, strTest_id);
jmethodID showMessage_id = (*env)-&GetMethodID(env, cls, &showMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(showMessage_id != NULL)
return (*env)-&CallIntMethod(env, thiz, showMessage_id, ctx,
strTitle, combine_jstring(env, strMessage, str));
l&&&&&&&& 新建实例调用:代码和代码分别为:
Button btn04 = (Button)findViewById(R.id.Button04);
btn04.setOnClickListener(newButton.OnClickListener()
publicvoid onClick(View v)
strTest = & [message has changed now]&;
int ret = jniInstanceShowMessage(JniDemoActivity.this,
&JNI test4&,&test callback in new instance&);
TextView tv = (TextView)findViewById(R.id.tv01);
if(ret == 0)
tv.setText(&test JNI new instance successed&);
tv.setText(&test JNI new instance fialed&);
jint Java_study_jnidemo_JniDemoActivity_jniInstanceShowMessage(JNIEnv* env, jobject thiz,
jobject ctx, jstring strTitle, jstring strMessage)
jclass cls = (*env)-&FindClass(env, &study/jnidemo/JniDemoActivity&);
if(cls != NULL)
// get instance
jmethodID constuctor_id = (*env)-&GetMethodID(env, cls, &&init&&, &()V&);
if(constuctor_id != NULL)
jobject obj = (*env)-&NewObject(env, cls, constuctor_id);
if(obj != NULL)
jmethodID strTest_id = (*env)-&GetMethodID(env, cls, &getTestString&,&()Ljava/lang/S&);
if(strTest_id != NULL)
str = (*env)-&CallObjectMethod(env, obj, strTest_id);
jmethodID showMessage_id = (*env)-&GetMethodID(env, cls,&showMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(showMessage_id != NULL)
return (*env)-&CallIntMethod(env, obj, showMessage_id, ctx,strTitle, combine_jstring(env, strMessage, str));
Test1 和Test2都是常规的调用,在这里不做解释了。现在我们看看Test3和Test4的区别,在Test3中,strTest
= & [message has changed now]& 在相应的代码中都做了赋值。但是在Test4中并没有改变,还是初始值。这是因为Test创建了一个新实例,和应用的JAVA代码中所赋值的实例并不是同一个。因此才出现了不同的结果。
附完整的JAVA和C代码
JAVAD代码: JniDemoActivity.java
package study.
import android.app.A
import android.app.AlertD
import android.os.B
import android.widget.B
import android.view.V
import android.widget.TextV
import android.content.C
import android.content.DialogI
publicclass JniDemoActivityextends Activity {
public StringstrTest =& [initial message]&;
/** Called when the activity is first created. */
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findAndModifyButton();
public String getTestString()
returnstrT
// 测试JAVA的NDK调用
publicnative String stringFromJNI();
// 测试C/C++中对JAVA函数的静态回调
publicnativestaticint jniStaticShowMessage(Context ctx, String strTitle, String strMessage);
// 测试实例中C/C++中对JAVA类的函数的调用
publicnativeint jniShowMessage(Context ctx, String strTitle, String strMessage);
// 测试创建新实例C/C++对JAVA类的函数的调用
publicnativeint jniInstanceShowMessage(Context ctx, String strTitle, String strMessage);
System.loadLibrary(&demo-jni&);
staticint staticShowMessage(Context ctx, String strTitle, String strMessage)
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle(strTitle);
builder.setMessage(strMessage);
builder.setPositiveButton(&确定&,
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int whichButton){
builder.show();
publicint showMessage(Context ctx, String strTitle, String strMessage)
returnstaticShowMessage(ctx, strTitle, strMessage);
privatevoid findAndModifyButton()
// 测试JAVA的NDK调用
Button btn01 = (Button)findViewById(R.id.Button01);
btn01.setOnClickListener(new Button.OnClickListener()
publicvoid onClick(View v)
TextView tv = (TextView)findViewById(R.id.tv01);
tv.setText(stringFromJNI());
showMessage(JniDemoActivity.this,&JNI test1&, stringFromJNI());
// 测试C/C++中对JAVA函数的静态回调
Button btn02 = (Button)findViewById(R.id.Button02);
btn02.setOnClickListener(new Button.OnClickListener()
publicvoid onClick(View v)
int ret =jniStaticShowMessage(JniDemoActivity.this,&JNI test2&, &test static callback Message&);
TextView tv = (TextView)findViewById(R.id.tv01);
if(ret == 0)
tv.setText(&test JNI static callback successed&);
tv.setText(&test JNI static callback fialed&);
// 测试实例中C/C++中对JAVA类的函数的调用
Button btn03 = (Button)findViewById(R.id.Button03);
btn03.setOnClickListener(new Button.OnClickListener()
publicvoid onClick(View v)
strTest = & [message has changed now]&;
int ret = jniShowMessage(JniDemoActivity.this,&JNI test3&, &test callback in current instance&);
TextView tv = (TextView)findViewById(R.id.tv01);
if(ret == 0)
tv.setText(&test JNI callback successed&);
tv.setText(&test JNI callback fialed&);
// 测试创建新实例C/C++对JAVA类的函数的调用
Button btn04 = (Button)findViewById(R.id.Button04);
btn04.setOnClickListener(new Button.OnClickListener()
publicvoid onClick(View v)
strTest = & [message has changed now]&;
int ret = jniInstanceShowMessage(JniDemoActivity.this,&JNI test4&, &test callback in new instance&);
TextView tv = (TextView)findViewById(R.id.tv01);
if(ret == 0)
tv.setText(&test JNI new instance successed&);
tv.setText(&test JNI new instance fialed&);
C代码 demo-jni.cpp
#include&string.h&
#include&jni.h&
// 加载此动态库时系统自动首先加载
jint JNI_OnLoad(JavaVM* vm, void *reserved)
if((*vm)-&GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)
return -1;
return JNI_VERSION_1_4;
Java_study_jnidemo_JniDemoActivity_stringFromJNI( JNIEnv* env,jobject thiz )
return (*env)-&NewStringUTF(env,&JniDemo, Hello from JNI!&);
combine_jstring(JNIEnv* env, jstring str1, jstring str2)
jboolean b_
constchar *s1 = (*env)-&GetStringUTFChars(env, str1, &b_ret);
constchar *s2 = (*env)-&GetStringUTFChars(env, str2, &b_ret);
int n1 = strlen(s1);
int n2 = strlen(s2);
char *new_str = (char *)malloc(n1+n2+1);
memset(new_str, 0, n1+n2+1);
strcat(new_str, s1);
strcat(new_str, s2);
jstring ret_str = (*env)-&NewStringUTF(env,(constchar *)new_str);
free(new_str);
return ret_
Java_study_jnidemo_JniDemoActivity_jniStaticShowMessage(JNIEnv* env, jobject thiz,
jobject ctx, jstring strTitle, jstring strMessage)
jclass cls = (*env)-&FindClass(env, &study/jnidemo/JniDemoActivity&);
jclass cls = (*env)-&GetObjectClass(env, thiz);
if(cls != NULL)
jmethodID id = (*env)-&GetStaticMethodID(env, cls,
&staticShowMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(id != NULL)
return (*env)-&CallStaticIntMethod(env, cls, id, ctx, strTitle, strMessage);
// 在当前已有的JAVA实例中调用
Java_study_jnidemo_JniDemoActivity_jniShowMessage(JNIEnv* env, jobject thiz,
jobject ctx, jstring strTitle, jstring strMessage)
jclass cls = (*env)-&GetObjectClass(env, thiz);
if(cls != NULL)
jmethodID strTest_id = (*env)-&GetMethodID(env, cls, &getTestString&,
&()Ljava/lang/S&);
if(strTest_id != NULL)
str = (*env)-&CallObjectMethod(env, thiz, strTest_id);
jmethodID showMessage_id = (*env)-&GetMethodID(env, cls, &showMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(showMessage_id != NULL)
return (*env)-&CallIntMethod(env, thiz, showMessage_id, ctx,
strTitle, combine_jstring(env, strMessage, str));
// 在新建JAVA实例中调用
Java_study_jnidemo_JniDemoActivity_jniInstanceShowMessage(JNIEnv* env, jobject thiz,
jobject ctx, jstring strTitle, jstring strMessage)
jclass cls = (*env)-&FindClass(env, &study/jnidemo/JniDemoActivity&);
if(cls != NULL)
// get instance
jmethodID constuctor_id = (*env)-&GetMethodID(env, cls, &&init&&, &()V&);
if(constuctor_id != NULL)
jobject obj = (*env)-&NewObject(env, cls, constuctor_id);
if(obj != NULL)
jmethodID strTest_id = (*env)-&GetMethodID(env, cls,&getTestString&,
&()Ljava/lang/S&);
if(strTest_id != NULL)
str = (*env)-&CallObjectMethod(env, obj, strTest_id);
jmethodID showMessage_id = (*env)-&GetMethodID(env, cls,&showMessage&,
&(Landroid/content/CLjava/lang/SLjava/lang/S)I&);
if(showMessage_id != NULL)
return (*env)-&CallIntMethod(env, obj, showMessage_id, ctx,
strTitle, combine_jstring(env, strMessage, str));
源代码下载地址:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:43736次
排名:千里之外
原创:17篇
评论:15条
(1)(1)(1)(3)(9)(2)2007年4月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。}

我要回帖

更多关于 android context 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信