一箫一剑平生意,负尽狂名十五年。这篇文章主要讲述android 编译调用C代码相关的知识,希望能为你提供帮助。
博客地址:www.zalezone.cn
前言
需求来源
这几天帮别人做一个简单的androidclient,也没什么功能。主要就是调用C代码来对手机的Wifi网络进行设置,于是也就引出了技术难点所在。怎样去调用C程序达到我们所须要的效果。
解决方式对于这个。我想出了两种解决方式:
- 第一种方案是利用JNI来进行本地调用。关于什么是JNI呢。JNI事实上是Java Native Interface的简称。也就是java本地接口,它提供了若干API实现了java和其它语言的通信(主要是C和C++)。
- 另外一种方法是将要运行的C代码编译成可运行文件,然后将这个可运行文件和程序一起打包成APK,在须要使用的时候调用这个可运行文件。
技术实现 可运行文件首先须要得到一个可运行文件。当然想要的到可运行文件并非想象中的那么简单,不是在linux中直接gcc就能到的,这里须要对C代码进行交叉编译获得能够在android机子上运行的可运行文件,详细怎样对C文件进行交叉编译,这里就不再赘述。大家能够上网查找一下。
另外,NDK也是个不错的工具。
资源存储这里的资源存储页算是个小坑。寻常我们在写java程序的时候,假设要打开一个文件的话就直接输入路径。比方假设所要使用的文件就在项目的文件夹下,直接输入文件名称就能够调用了,可是这里的执行环境是嵌入式设备,不是PC,这就涉及到一个问题,资源怎样存储了。
【android 编译调用C代码】
这里先谈一下Android中的asset目录和res/raw目录的异同:
- 同样点
- 两者文件夹下的文件在打包后都会原封不动的保存在apk包中,不会被编译成二进制。
- 两者文件夹下的文件在打包后都会原封不动的保存在apk包中,不会被编译成二进制。
- 不同点
- res/raw中的文件会被映射到R.java中。訪问的时候直接使用资源ID就可以。而assets文件夹下的文件不会被映射到R.java。
- res/raw不能够有文件夹结构,而assets文件夹下能够再建立文件夹。
- res/raw中的文件会被映射到R.java中。訪问的时候直接使用资源ID就可以。而assets文件夹下的文件不会被映射到R.java。
1 |
InputStream is =getResources().openRawResource(R.id.filename); |
123 |
AssetManager am = null; am = getAssets(); InputStream is = am.open("filename"); |
尽管读取是成功了,可是要用shell脚本运行的话,应该在手机的存储上应该有这个文件,光是读取的话在手机里面是找不见的,所以我们须要一个存文件的操作。
这里我写了一个存文件的函数。当中将获取assets中数据的方法也结合进去了。
123456789101112131415 |
publicvoid copyDataToSD(String outFileName)throws IOException{ InputStream myInputStream; OutputStream myOutputStream = new FileOutputStream(outFileName); myInputStream = this.getAssets().open("a.out"); byte[] buffer = new byte[1024]; int length = myInputStream.read(buffer); while (length > 0) {myOutputStream.write(buffer, 0, length); length = myInputStream.read(buffer); } myOutputStream.flush(); myInputStream.close(); myOutputStream.close(); } |
12 |
private static String EXE_PATH = "data/data/com.example.g3wifi/a.out"; private static File exe_file; |
12345678 |
publicvoid exeC(String cmd)throws IOException{ Runtime runtime =Runtime.getRuntime(); Process process = runtime.exec(cmd); //Process process = runtime.exec(new String[]{"su","reboot"}); //能够运行两条命令//这能够得到运行shell命令后的结果BufferedReader ie = new BufferedReader(new InputStreamReader(process.getErrorStream())); } |
推荐阅读
- Android对UDP组播接收数据的有限支持
- app 设计原则 ,步骤
- android实现gif图与文字混排
- android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本)
- 必须尝试的10种最佳Discord音板合集
- Mac的11款最佳文件粉碎机软件合集
- Android和iPhone的5大密码生成器应用程序合集
- Windows和Mac的13款最佳免费流程图软件合集
- Windows的13款最佳文件复制实用软件合集