博客地址:www.zalezone.cn

前言

需求来源

这几天帮别人做一个简单的androidclient,也没什么功能,主要就是调用C代码来对手机的Wifi网络进行设置。于是也就引出了技术难点所在,怎样去调用C程序达到我们所须要的效果。

解决方式

对于这个,我想出了两种解决方式:

  1. 第一种方案是利用

    fr=aladdin" target="_blank" rel="external">JNI来进行本地调用。关于什么是JNI呢,JNI事实上是Java Native Interface的简称,也就是java本地接口,它提供了若干API实现了java和其它语言的通信(主要是C和C++)。

  2. 另外一种方法是将要运行的C代码编译成可运行文件,然后将这个可运行文件和程序一起打包成APK,在须要使用的时候调用这个可运行文件。

终于选择

最后我选择了另外一种方案,理由是另外一种方法在我已经有了可运行文件的条件下整体来说比較简单。可操作性强。

而第一种方案的话由于还要下载android的NDK,NDK是一系列工具的集合,提供了帮助开发人员高速开发C或则C++的动态库。并能自己主动将so和java应用一起打包成apk。十分方便。

技术实现

可运行文件

首先须要得到一个可运行文件。当然想要的到可运行文件并非想象中的那么简单。不是在linux中直接gcc就能到的,这里须要对C代码进行

fr=aladdin" target="_blank" rel="external">交叉编译获得能够在android机子上运行的可运行文件。详细怎样对C文件进行交叉编译。这里就不再赘述,大家能够上网查找一下。另外,NDK也是个不错的工具。

资源存储

这里的资源存储页算是个小坑,寻常我们在写java程序的时候,假设要打开一个文件的话就直接输入路径,比方假设所要使用的文件就在项目的文件夹下,直接输入文件名称就能够调用了,可是这里的执行环境是嵌入式设备,不是PC,这就涉及到一个问题。资源怎样存储了。

这里先谈一下Android中的asset目录res/raw目录的异同:

  • 同样点

    • 两者文件夹下的文件在打包后都会原封不动的保存在apk包中。不会被编译成二进制。
  • 不同点
    • res/raw中的文件会被映射到R.java中,訪问的时候直接使用资源ID就可以。而assets文件夹下的文件不会被映射到R.java。

    • res/raw不能够有文件夹结构,而assets文件夹下能够再建立文件夹。

资源获取

这里顺带说一下res/raw下的文件资源的读取方法,通过下面方式获取输入流来进行写操作

1
InputStream is =getResources().openRawResource(R.id.filename);

接下来才是我用到的读取assets下的方法,相同也是通过获取输入流的方式来进行写操作

1
2
3
AssetManager am = null;
am = getAssets();
InputStream is = am.open("filename");

注意点:据说Assert仅仅能放单个文件不超过1M的文件,可是不是真的详细还没考证过,假设碰到问题了应该考虑一下这个注意点。

尽管读取是成功了。可是要用shell脚本运行的话。应该在手机的存储上应该有这个文件,光是读取的话在手机里面是找不见的,所以我们须要一个存文件的操作。

这里我写了一个存文件的函数,当中将获取assets中数据的方法也结合进去了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void 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();
}

然后我定义的传入的outFileName是定义的文件路径加文件名称

1
2
private static String EXE_PATH = "data/data/com.example.g3wifi/a.out";
private static File exe_file;

shell命令运行

到这里的话就是“万事俱备,仅仅欠东风”了,我们须要运行所得到的可运行文件,由于android是基于linux的,所以一些主要的命令还是支持的。在android中要运行shell命令的话就按例如以下格式就可以:

1
2
3
4
5
6
7
8
public void 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 编译调用C代码的更多相关文章

  1. 【转】Android 学习笔记——利用JNI技术在Android中调用、调试C++代码

    原文网址:http://cherishlc.iteye.com/blog/1756762 在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在And ...

  2. android112 c代码打印日志,c反编译调用java

    activity: package com.itheima.ccalljava; import android.os.Bundle; import android.app.Activity; impo ...

  3. [转][android][利用JNI技术在Android中调用、调试C++代码]

    在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在Android中会生成Linux系统下的.so文件(好吧,其实我基本没用过Linux). 没写过 ...

  4. Ubuntu系统下实现Android工程调用独立编译的C++程序和GMP、PBC库

    目的: 实现使用C++编写代码供Android工程调用.C++代码中可以使用STL库,也可以使用常用的由源码编译生成的库,如PBC.因为PBC是基于GMP库的,所以这里只记录了GMP和PBC库的编译安 ...

  5. Android开发:APK的反编译(获取代码和资源文件)

    一.反编译工具: 1.APKTool: APKTool是由GOOGLE提供的APK编译工具,能够完成反编译及回编译apk的工作.同时,它也有着安装反编译系统apk所需要的framework-res框架 ...

  6. android开发中调用python代码(带参数)

    android开发主要用到的是java代码,但是当开发涉及到一些算法时,往往用python可以提高软件的运行速度,也更加便捷,这里分享自己项目调用python代码的方式,主要有以下几个步骤(个人方法, ...

  7. 如何使用g++编译调用dll的c++代码

    本文将有以下4个部分来讲如何使用g++编译调用dll的c++代码. 1.如何调用dll 2.动态链接和静态链接的区别 3.g++的编译参数以及如何编译调用dll的c++代码 4.总结 1.如何调用dl ...

  8. apt 根据注解,编译时生成代码

    apt: @Retention后面的值,设置的为CLASS,说明就是编译时动态处理的.一般这类注解会在编译的时候,根据注解标识,动态生成一些类或者生成一些xml都可以,在运行时期,这类注解是没有的~~ ...

  9. android JNI调用(转)

    Android jni开发资料--NDK环境搭建 android开发人员注意了 谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwi ...

随机推荐

  1. C / C++算法学习笔记(7)-双向冒泡

    原始地址:双向冒泡 通常的冒泡是单向的,而这里是双向的,也就是说还要进行反向的工作. 代码看起来复杂,仔细理一下就明白了,是一个来回震荡的方式. 写这段代码的作者认为这样可以在冒泡的基础上减少一些交换 ...

  2. Delphi “Invalid floating point operation.”错误的解决方法(使用System单元提供的Set8087CW函数禁用浮点异常)

    这两天用webbrower写东西,有时候打开SSL加密网站时会出现”Invalid floating point operation.”的错误,上网搜了下,把解决方法贴上. 导致原因 在Delphi2 ...

  3. Qt 的内部进程通信机制

    Qt 的内部进程通信机制 续欣 (xxin76@hotmail.com), 博士.大学讲师 2004 年 4 月 01 日 Qt 作为一种跨平台的基于 C++ 的 GUI 系统,能够提供给用户构造图形 ...

  4. 玩转Windows服务系列——创建Windows服务

    原文:玩转Windows服务系列——创建Windows服务 创建Windows服务的项目 新建项目->C++语言->ATL->ATL项目->服务(EXE) 这样就创建了一个Wi ...

  5. [Android学习笔记]View的draw过程学习

    View从创建到显示到屏幕需要经历几个过程: measure -> layout -> draw measure过程:计算view所占屏幕大小layout过程:设置view在屏幕的位置dr ...

  6. unable to load default svn client 和 Eclipse SVN 插件与TortoiseSVN对应关系

    (一)unable to load default svn client 在Win7下的Eclipse,安装了subclipse 1.10.x,已经选中了subclipse和subversion Cl ...

  7. 利用Node.js实现模拟Session验证的登陆

    1.身份验证和用户登陆 在一般的Web应用上,假设要实现用户登陆,最经常使用,也是最简单的方法就是使用Session,主要的思路是在Session中保留一些用户身份信息,然后每次在Session中取, ...

  8. Android Studio Gradle 添加.so 支持文件

    近期发展Android Wear 关注商品.官员Demo所有gradle 工程. 当然,我也用eclipse配置一个可行的环境. 问题来了,eclipse,android studio 开发 andr ...

  9. leetcode解析回文子串拆分

    转载请注明来自souldak,微博:@evagle Given a string s, partition s such that every substring of the partition i ...

  10. uva11426(莫比乌斯反演)

    传送门:GCD Extreme (II) 题意:给定n(n<=4000000),求G G=0 for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) ...