多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > 綜合技術(shù) > Android Studio JNI開發(fā)基礎(chǔ)篇

Android Studio JNI開發(fā)基礎(chǔ)篇

來源:程序員人生   發(fā)布時(shí)間:2016-09-27 09:20:52 閱讀次數(shù):2657次

      • 前言
      • 環(huán)境搭建
      • 創(chuàng)建Native代碼
      • 使用

前言

開發(fā)進(jìn)程中,為了數(shù)據(jù)交互安全,決定對(duì)數(shù)據(jù)進(jìn)行des加密,然落后行前后交互;但是,如果密鑰放置在android代碼里面,就算是混淆,反編譯也很容易讓人拿到密鑰,數(shù)據(jù)加密的安全度不高,因此斟酌通過jni來返回1個(gè)密鑰對(duì)數(shù)據(jù)進(jìn)行加解密。從而到達(dá)數(shù)據(jù)的安全性。

環(huán)境搭建

  • 下載NDK
    通過android studio去下載NDK插件;打開File–>Project Structure–>SDK Location–>Android NDK Location,以下圖:

    如果是第1次,沒有下載NDK插件,在紅色箭頭的地方有個(gè)按鈕用于下載安裝,點(diǎn)擊等待下載便可,使用AS下載的NDK會(huì)默許反正你的sdk的目錄路徑下;亦或選中藍(lán)色剪頭的按鈕選擇已下載好的NDK;點(diǎn)擊“OK”,配置成功以后,會(huì)在local.properties文件下看見相應(yīng)的路徑指向,以下圖:

  • 配置NDK環(huán)境變量

    • 創(chuàng)建NDK_HOME
      右鍵我的電腦–>屬性–>高級(jí)系統(tǒng)設(shè)置–>環(huán)境變量–>系統(tǒng)變量–>新建–>創(chuàng)建1個(gè)“NDK_HOME”,NDK的路徑就是上1步中配置的路徑,以下圖:

    • 添加path
      系統(tǒng)變量中找到Path–>編輯,將;%NDK_HOME%添加至path中,以下圖:

    • 驗(yàn)證配置是不是成功
      在cmd下輸入“ndk-build”指令,如果出現(xiàn)下圖結(jié)果,即配置成功:

創(chuàng)建Native代碼

  • 在java目錄下創(chuàng)建1個(gè)帶有native方法的java文件

    /** * native */ public class SmartCardJniUtil { /** * 加載so庫 */ static { System.loadLibrary("SCJniUtil"); } /** * 獲得密鑰 * @return 密鑰 */ public native String getKey(); }
  • 通過Build–>Make Project項(xiàng)目
    成功以后,在app–>intermediates–>classes–>debug–>個(gè)人項(xiàng)目路徑下找到上面新建的native類的class文件,以下圖:

  • 生成頭文件

    • File—settings—plugins下勾選Termainal

    • 指令生成頭文件
      javah -d jni -classpath ;….\build\intermediates\classes\debug 類的包名。
      按著以上說明,首先通過cd app\src\main跳轉(zhuǎn)到main目錄下,然后輸入以下指令:
      javah -d jni -classpath E:**\sdk\platforms\android⑵0\android.jar;….\build\intermediates\classes\debug com.a.b.c.SmartCardJniUtil
      以下圖:

      成功以后會(huì)在main目錄下多1個(gè)jni文件,并包括了1個(gè).h的頭文件,以下圖:

    • 創(chuàng)建.c文件
      在jni目錄下右鍵–>New–>C/C++ Source File創(chuàng)建1個(gè)SmartCardJniUtil.c文件,然后引入頭文件,返回密鑰,以下代碼:

      #include "com_a_b_c_SmartCardJniUtil.h" JNIEXPORT jstring JNICALL Java_com_a_b_c_SmartCardJniUtil_getKey (JNIEnv *env, jobject jobject1) { return (*env)->NewStringUTF(env, "1122334455667788"); };
  • 在build.gradle文件下添加配置,代碼以下:

    buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' ndk { moduleName "SCJniUtil" //生成的so名字 abiFilters "armeabi", "armeabi-v7a", "x86" //輸出指定3種abi體系結(jié)構(gòu)下的so庫。 } } debug { ndk { moduleName "SCJniUtil" //生成的so名字 abiFilters "armeabi", "armeabi-v7a", "x86" //輸出指定3種abi體系結(jié)構(gòu)下的so庫。 } } } sourceSets { main { jniLibs.srcDirs = ['libs'] } }
  • 清算并重新make項(xiàng)目,生成so庫,以下圖:

  • 關(guān)于Android.mk文件說明
    通過eclipse開發(fā)jni的時(shí)候,需要進(jìn)行1個(gè)Android.mk文件的配置,但是Android Studio中并沒有做,沒有做不代表沒有,AS自動(dòng)幫我們生成了,不需要我們自己去創(chuàng)建并配置,以下圖:

  • 混淆文件中添加不混淆native的配置

    -keepclasseswithmembernames class * { native <methods>; }

使用

  • 通過jni獲得密鑰
    當(dāng)以上步驟完成以后,實(shí)例化native對(duì)象,調(diào)用相應(yīng)的方法便可獲得到相應(yīng)的結(jié)果,代碼以下:

    //實(shí)例化對(duì)象 SmartCardJniUtil jniUtil = new SmartCardJniUtil(); //獲得密鑰 jniUtil.getKey()
  • des加解密工具

    public class DesUtil { /** * 數(shù)據(jù)加密,算法(DES) * * @param data 要進(jìn)行加密的數(shù)據(jù) * @return 加密后的數(shù)據(jù) */ public static String encryptBasedDes(String data, String keyStr) { keyStr = StringUtilsSimple.leftPad(keyStr, 16, "0"); byte[] DES_KEY = ByteUtil.hexStr2Byte(keyStr); String encryptedData = null; try { // DES算法要求有1個(gè)可信任的隨機(jī)數(shù)源 SecureRandom sr = new SecureRandom(); DESKeySpec deskey = new DESKeySpec(DES_KEY); // 創(chuàng)建1個(gè)密匙工廠,然后用它把DESKeySpec轉(zhuǎn)換成1個(gè)SecretKey對(duì)象 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(deskey); // 加密對(duì)象 Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key, sr); // 加密,并把字節(jié)數(shù)組編碼成字符串 encryptedData = ByteUtil.hexToStr(cipher.doFinal(data.getBytes())); } catch (Exception e) { // log.error("加密毛病,毛病信息:", e); throw new RuntimeException("加密毛病,毛病信息:", e); } return encryptedData; } /** * 數(shù)據(jù)解密,算法(DES) * * @param cryptData 加密數(shù)據(jù) * @return 解密后的數(shù)據(jù) */ public static String decryptBasedDes(String cryptData, String keyStr) { keyStr = StringUtilsSimple.leftPad(keyStr, 16, "0"); byte[] DES_KEY = ByteUtil.hexStr2Byte(keyStr); String decryptedData = null; try { // DES算法要求有1個(gè)可信任的隨機(jī)數(shù)源 SecureRandom sr = new SecureRandom(); DESKeySpec deskey = new DESKeySpec(DES_KEY); // 創(chuàng)建1個(gè)密匙工廠,然后用它把DESKeySpec轉(zhuǎn)換成1個(gè)SecretKey對(duì)象 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(deskey); // 解密對(duì)象 Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key, sr); // 把字符串解碼為字節(jié)數(shù)組,并解密 decryptedData = new String(cipher.doFinal(ByteUtil.hexStr2Byte(cryptData))); } catch (Exception e) { // log.error("解密毛病,毛病信息:", e); throw new RuntimeException("解密毛病,毛病信息:", e); } return decryptedData; } public static void main(String[] args) { // TODO Auto-generated method stub String str = "123456789"; // DES數(shù)據(jù)加密 long time = System.currentTimeMillis(); String s1 = encryptBasedDes(str, "1122334411223344"); System.out.println("time1:" + (System.currentTimeMillis() - time)); System.out.println(s1); // DES數(shù)據(jù)解密 long time2 = System.currentTimeMillis(); String s2 = decryptBasedDes(s1, "1122334411223344"); System.out.println("time2:" + (System.currentTimeMillis() - time2)); System.err.println(s2); } }
  • 文本左右補(bǔ)位的工具

    public class StringUtilsSimple { /** * A String for a space character. * * @since 3.2 */ public static final String SPACE = " "; /** * <p>The maximum size to which the padding constant(s) can expand.</p> */ private static final int PAD_LIMIT = 8192; // Empty checks // ----------------------------------------------------------------------- /** * <p> * Checks if a CharSequence is empty ("") or null. * </p> * * <pre> * StringUtils.isEmpty(null) = true * StringUtils.isEmpty("") = true * StringUtils.isEmpty(" ") = false * StringUtils.isEmpty("bob") = false * StringUtils.isEmpty(" bob ") = false * </pre> * * <p> * NOTE: This method changed in Lang version 2.0. It no longer trims the * CharSequence. That functionality is available in isBlank(). * </p> * * @param cs * the CharSequence to check, may be null * @return {@code true} if the CharSequence is empty or null * @since 3.0 Changed signature from isEmpty(String) to * isEmpty(CharSequence) */ public static boolean isEmpty(final CharSequence cs) { return cs == null || cs.length() == 0; } /** * <p> * Left pad a String with a specified String. * </p> * * <p> * Pad to a size of {@code size}. * </p> * * <pre> * StringUtils.leftPad(null, *, *) = null * StringUtils.leftPad("", 3, "z") = "zzz" * StringUtils.leftPad("bat", 3, "yz") = "bat" * StringUtils.leftPad("bat", 5, "yz") = "yzbat" * StringUtils.leftPad("bat", 8, "yz") = "yzyzybat" * StringUtils.leftPad("bat", 1, "yz") = "bat" * StringUtils.leftPad("bat", -1, "yz") = "bat" * StringUtils.leftPad("bat", 5, null) = " bat" * StringUtils.leftPad("bat", 5, "") = " bat" * </pre> * * @param str * the String to pad out, may be null * @param size * the size to pad to * @param padStr * the String to pad with, null or empty treated as single space * @return left padded String or original String if no padding is necessary, * {@code null} if null String input */ public static String leftPad(final String str, final int size, String padStr) { if (str == null) { return null; } if (isEmpty(padStr)) { padStr = SPACE; } final int padLen = padStr.length(); final int strLen = str.length(); final int pads = size - strLen; if (pads <= 0) { return str; // returns original String when possible } if (padLen == 1 && pads <= PAD_LIMIT) { return leftPad(str, size, padStr.charAt(0)); } if (pads == padLen) { return padStr.concat(str); } else if (pads < padLen) { return padStr.substring(0, pads).concat(str); } else { final char[] padding = new char[pads]; final char[] padChars = padStr.toCharArray(); for (int i = 0; i < pads; i++) { padding[i] = padChars[i % padLen]; } return new String(padding).concat(str); } } /** * <p>Left pad a String with a specified character.</p> * * <p>Pad to a size of {@code size}.</p> * * <pre> * StringUtils.leftPad(null, *, *) = null * StringUtils.leftPad("", 3, 'z') = "zzz" * StringUtils.leftPad("bat", 3, 'z') = "bat" * StringUtils.leftPad("bat", 5, 'z') = "zzbat" * StringUtils.leftPad("bat", 1, 'z') = "bat" * StringUtils.leftPad("bat", -1, 'z') = "bat" * </pre> * * @param str the String to pad out, may be null * @param size the size to pad to * @param padChar the character to pad with * @return left padded String or original String if no padding is necessary, * {@code null} if null String input * @since 2.0 */ public static String leftPad(final String str, final int size, final char padChar) { if (str == null) { return null; } final int pads = size - str.length(); if (pads <= 0) { return str; // returns original String when possible } if (pads > PAD_LIMIT) { return leftPad(str, size, String.valueOf(padChar)); } return repeat(padChar, pads).concat(str); } /** * <p>Returns padding using the specified delimiter repeated * to a given length.</p> * * <pre> * StringUtils.repeat('e', 0) = "" * StringUtils.repeat('e', 3) = "eee" * StringUtils.repeat('e', -2) = "" * </pre> * * <p>Note: this method doesn't not support padding with * <a href="http://www.unicode.org/glossary/#supplementary_character">Unicode Supplementary Characters</a> * as they require a pair of {@code char}s to be represented. * If you are needing to support full I18N of your applications * consider using {@link #repeat(String, int)} instead. * </p> * * @param ch character to repeat * @param repeat number of times to repeat char, negative treated as zero * @return String with repeated character * @see #repeat(String, int) */ public static String repeat(final char ch, final int repeat) { final char[] buf = new char[repeat]; for (int i = repeat - 1; i >= 0; i--) { buf[i] = ch; } return new String(buf); } /** * <p>Right pad a String with a specified String.</p> * * <p>The String is padded to the size of {@code size}.</p> * * <pre> * StringUtils.rightPad(null, *, *) = null * StringUtils.rightPad("", 3, "z") = "zzz" * StringUtils.rightPad("bat", 3, "yz") = "bat" * StringUtils.rightPad("bat", 5, "yz") = "batyz" * StringUtils.rightPad("bat", 8, "yz") = "batyzyzy" * StringUtils.rightPad("bat", 1, "yz") = "bat" * StringUtils.rightPad("bat", -1, "yz") = "bat" * StringUtils.rightPad("bat", 5, null) = "bat " * StringUtils.rightPad("bat", 5, "") = "bat " * </pre> * * @param str the String to pad out, may be null * @param size the size to pad to * @param padStr the String to pad with, null or empty treated as single space * @return right padded String or original String if no padding is necessary, * {@code null} if null String input */ public static String rightPad(final String str, final int size, String padStr) { if (str == null) { return null; } if (isEmpty(padStr)) { padStr = SPACE; } final int padLen = padStr.length(); final int strLen = str.length(); final int pads = size - strLen; if (pads <= 0) { return str; // returns original String when possible } if (padLen == 1 && pads <= PAD_LIMIT) { return rightPad(str, size, padStr.charAt(0)); } if (pads == padLen) { return str.concat(padStr); } else if (pads < padLen) { return str.concat(padStr.substring(0, pads)); } else { final char[] padding = new char[pads]; final char[] padChars = padStr.toCharArray(); for (int i = 0; i < pads; i++) { padding[i] = padChars[i % padLen]; } return str.concat(new String(padding)); } } /** * <p>Right pad a String with a specified character.</p> * * <p>The String is padded to the size of {@code size}.</p> * * <pre> * StringUtils.rightPad(null, *, *) = null * StringUtils.rightPad("", 3, 'z') = "zzz" * StringUtils.rightPad("bat", 3, 'z') = "bat" * StringUtils.rightPad("bat", 5, 'z') = "batzz" * StringUtils.rightPad("bat", 1, 'z') = "bat" * StringUtils.rightPad("bat", -1, 'z') = "bat" * </pre> * * @param str the String to pad out, may be null * @param size the size to pad to * @param padChar the character to pad with * @return right padded String or original String if no padding is necessary, * {@code null} if null String input * @since 2.0 */ public static String rightPad(final String str, final int size, final char padChar) { if (str == null) { return null; } final int pads = size - str.length(); if (pads <= 0) { return str; // returns original String when possible } if (pads > PAD_LIMIT) { return rightPad(str, size, String.valueOf(padChar)); } return str.concat(repeat(padChar, pads)); } }
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 不卡欧美| 亚洲精品久久一区二区无卡 | 尤物视频在线看 | 国产一区免费在线观看 | 欧美伊人久久大香线蕉在观 | 久久精品a一国产成人免费网站 | 97综合| 宇都宫紫苑在线播放ed2k | 亚洲另类视频在线观看 | 2019最新中文字幕 | 中文字幕第八页 | free俄罗斯性xxxxhd大陆 | 91欧美精品综合在线观看 | 国产极品美乳尤物在线观看 | 精品久久九九 | 中文天堂在线视频 | 亚州中文字幕 | 久久久久色 | 欧美日韩性视频 | 亚洲综合区图片小说区 | 大bbw另类交hd| 亚洲网站www | 欧美极品尤物在线播放一级 | 欧美男同志高清videosbest | 欧美日韩精品国产一区二区 | 久久五月网 | 国产亚洲一区二区三区在线 | 亚洲日本黄色 | 欧美性猛交xxxx| 国产亚洲欧美一区 | 99999久爱视频在线观看 | 午夜影院亚洲 | 日韩免费精品 | 国产一区精品 | 亚洲欧美综合乱码精品成人网 | 免费www | 另类小说图片 | 亚洲国产高清一区二区三区 | 亚洲视频一区 | 亚洲一区国产 | 偷拍区小说区图片区另类呻吟 |