Android技术12:NDK模拟登陆

由于Android应用程序大多使用Java编写,所有很容易通过反编译获取源代码,因此为了保持核心算法,逻辑的安全性,大多应用程序将该部分使用c或c++实现,例如:用户的登陆,底层采用c或c++代码编写。下面将演示简单的c语言验证用户名和密码正确性,实现登录。

1.创建Android应用程序

创建过程与一般android应用程序类似,添加2个EditText和1个Button,示例图如下

布局文件

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6     <EditText
 7         android:id="@+id/et1"
 8         android:layout_width="fill_parent"
 9         android:layout_height="wrap_content"
10         android:hint="用户名"/>
11      <EditText
12         android:id="@+id/et2"
13         android:layout_width="fill_parent"
14         android:layout_height="wrap_content"
15         android:hint="密码"/>
16      <Button
17         android:id="@+id/bt1"
18         android:layout_width="wrap_content"
19         android:layout_height="wrap_content"
20         android:hint="登录"/>
21 </LinearLayout>

2.添加Native方法

public native int login(String username,String password);

3.获取相应的头文件

D:\Android\ndk_login\src>javah com.forsta.login.MainActivity

得到com_forsta_login_MainActivity.h文件

com_forsta_login_MainActivity.h

 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include <jni.h>
 3 /* Header for class com_forsta_login_MainActivity */
 4
 5 #ifndef _Included_com_forsta_login_MainActivity
 6 #define _Included_com_forsta_login_MainActivity
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 /*
11  * Class:     com_forsta_login_MainActivity
12  * Method:    login
13  * Signature: (Ljava/lang/String;Ljava/lang/String;)I
14  */
15 JNIEXPORT jint JNICALL Java_com_forsta_login_MainActivity_login
16   (JNIEnv *, jobject, jstring, jstring);
17
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif

4.添加jni文件夹,Android.mk,login.c文件

login.c

 1 #include <stdio.h>
 2 #include <jni.h>
 3 #include <malloc.h>
 4 #include <string.h>
 5 #include "com_forsta_login_MainActivity.h"
 6
 7 /**
 8  * 返回值 char* 这个代表char数组的首地址
 9  *  Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串
10  */
11 char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)
12 {
13      char*   rtn   =   NULL;
14      jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String"); //String
15      jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312");  // 得到一个java字符串 "GB2312"
16      jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312");
17      jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312");
18      jsize   alen   =   (*env)->GetArrayLength(env,barr); // byte数组的长度
19      jbyte*   ba   =   (*env)->GetByteArrayElements(env,barr,JNI_FALSE);
20      if(alen   >   0)
21      {
22       rtn   =   (char*)malloc(alen+1);         //"\0"
23       memcpy(rtn,ba,alen);
24       rtn[alen]=0;
25      }
26      (*env)->ReleaseByteArrayElements(env,barr,ba,0);  //
27      return rtn;
28 }
29
30 //登录判断逻辑
31 int login(char*username,char*password)
32 {
33     char*user="forsta";
34     char*pwd="123456";
35     int i=0,j=0;
36     if(strcmp(user,username)!=0 ||strcmp(password,pwd)!=0){
37         return 404;
38     }
39     return 200;
40 }
41
42 JNIEXPORT jint JNICALL Java_com_forsta_login_MainActivity_login
43   (JNIEnv *env, jobject obj, jstring username, jstring pwd){
44     char*name=Jstring2CStr(env,username);
45     char*password=Jstring2CStr(env,pwd);
46     return login(name,password);
47
48 }

Android.mk

1 LOCAL_PATH := $(call my-dir)
2 include $(CLEAR_VARS)
3 LOCAL_MODULE    := login
4 LOCAL_SRC_FILES := login.c
5 include $(BUILD_SHARED_LIBRARY)

5.编译,加载库文件

[email protected] /cygdrive/d/android/ndk_login
$ ndk-build
Android NDK: WARNING: APP_PLATFORM android-18 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml
[armeabi] Compile thumb : login <= login.c
jni/login.c: In function ‘Jstring2CStr‘:
jni/login.c:22:4: warning: incompatible implicit declaration of built-in function ‘memcpy‘ [enabled by default]
[armeabi] SharedLibrary : liblogin.so
[armeabi] Install : liblogin.so => libs/armeabi/liblogin.so

加载库文件

static{
System.loadLibrary("login");
}

6.登录实现

 1 bt.setOnClickListener(new OnClickListener() {
 2
 3             @Override
 4             public void onClick(View v) {
 5                 String username=t1.getText().toString().trim();
 6                 String pwd=t2.getText().toString().trim();
 7                 int result =login(username,pwd);
 8                 if(result==200)
 9                 {
10                     Toast.makeText(getApplicationContext(), "登录成功,code=200", 1).show();
11                 }else{
12
13                     Toast.makeText(getApplicationContext(), "登录失败,code=404", 1).show();
14                 }
15
16             }
17         });

7.显示结果

Android技术12:NDK模拟登陆

时间: 2024-07-31 19:37:55

Android技术12:NDK模拟登陆的相关文章

Android技术9:Android NDK日志调试

在Android中我们经常使用Log来调试程序,NDK中也为我们提供输出日志的方法. 1.引入头文件<android/log.h> #include<android/log.h> 2.定义宏 #define LOG_TAG "System.out.c"#define LOGD(...) _android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,_VA_ARGS_)#define LOGI(...) _android_log_pri

Android技术13:NDK中无法返回中文问题解决

1问题 为了加强软件的安全性,将http请求,封装在jni中,即通过c语言实现http请求,返回字符串.然而字符串往往包含中文,当返回类型为jstring时,就会出现JNI WARNING: illegal continuation byte 0xd0这错误,这是因为jni中c文件有中文, 中文不能被识别.无法使用(*env)->NewStringUTF(env,s);返回字符串. 2.方案 2.1将native方法返回类型为byte数组  例如:private native byte[] ge

android开发资源网站,下载各版本SDK源码、Android Studio、NDK等

http://www.androiddevtools.cn/ AndroidDevTools简介 Android Dev Tools官网地址:www.androiddevtools.cn 收集整理Android开发所需的Android SDK.开发中用到的工具.Android开发教程.Android设计规范,免费的设计素材等. 欢迎大家推荐自己在Android开发过程中用的好用的工具.学习开发教程.用到设计素材,欢迎Star.Fork . 如果你对翻译英文的Android开发技术文章感兴趣,欢

模拟登陆、Cookie传递

---恢复内容开始--- 上个月月底把模拟登陆的问题解决了,现在有时间就正好记录并复习一下. 主要使用httpclient 来进行模拟登陆 首先做一个登陆布局  一直以来都是简单拖几个控件 没有啥特效  这次我想使用一点 Material Design设计风格    查了一下 TextInputLayout这个控件  还不错 TextInputLayout 来自于 Android Design Support Library    可以让edittext的hint在用户输入的时候  自动跳到上方

Android技术10:Java与C语言之间简单数据的传递

由于C语言和Java语言之间很多类型不一致性,因此使用native时,需要数据类型转换.下面演示分别传递整型,字符串,整型数组,Java静态方法传递数据. 1.创建native方法 我们单独创建一个NativeClass类来存放native方法 1 package com.forsta.ndk; 2 3 public class NativeClass { 4 public native int add(int x,int y); 5 public native String showStrin

爬虫模拟登陆校园网并抓取作业

首先打开校园网的网络教学平台http://eol.zhbit.com/homepage/common/ 找到相应的表单代码 用户名的name是IPT_LOGINUSERNAME 密码的name是IPT_LOGINPASSWORD 提交的地址是http://www.zhbit.com/homepage/common/login.jsp 通过浏览器的抓包发现确实只有这两个数据提交 提交成功后页面变成这样 点击进入 发现地址已经变成http://eol.zhbit.com/main.jsp 所以我们的

Python——新浪微博爬虫之模拟登陆

在编写微博爬虫的过程中,免不了要进行模拟登录,因为新浪微博不登陆只能访问少量的微博信息. 然而,由于新浪微博的反爬虫功能在不断更新,例如改变了密码的加密算法(RSA),以前的一些模拟登陆方式已经不适用了.所以一开始试了好几种方法,均不能成功.后来受http://www.jb51.net/article/46053.htm启发,已经实现了. 目前,亲测能用的步骤是:①通过预登录,使用GET方法,获得登录所需的servertime, nonce, pubkey, rsakv:②使用encode64加

Android技术18:Android中Adapter类详解

1.Adapter设计模式 Android中adapter接口有很多种实现,例如,ArrayAdapter,BaseAdapter,CursorAdapter,SimpleAdapter,SimpleCursorAdapter等,他们分别对应不同的数据源.例如,ArrayAdater对应List和数组数据源,而CursorAdapter对应Cursor对象(一般从数据库中获取的记录集).这些Adapter都需要getView方法返回当前列表项显示的View对象.当Model发生改变时,会调用Ba

Android技术22:Android中AIDL

在Android中进程内部通过全局变量,文件,preference,数据库作为数据的载体实现数据共享和通信.然后在进程之间则需要借助Binder实现IPC调用.Android进程通信框架:服务端,客户端,Linux binder驱动.Binder驱动成为连接两端的桥梁.我们首先通过aidl语言实现一个简单的多进程通信.具体实现步骤如下: 1.定义aidl文件 IService.aidl,定义一个接口,test() ,不包含负责的类和数据. 1 package com.demo.ipc; 2 3