这个其实就是个人的一个小小的兴趣,用C/C++写一个小程序放在Android的系统中,然后用Java写一个Android的UI程序来调用这个C/C++的程序。这里总结了实现这个功能的一些步骤和遇到的问题。蛮有意思的。


这里参考了下面两篇博文,主要是关于搭建arm-linux-gcc交叉编译环境的,非常有帮助,感谢他们的分享。

http://blog.csdn.net/super005/article/details/6369577

http://mawenhao19930620.blog.163.com/blog/static/128575361201212211291763/

http://www.cnblogs.com/huaping-audio/archive/2009/08/27/1555089.html


 

这里主要分四步:

1)搭建一个交叉编译环境,这里用的是Ubuntu的虚拟机来编译出一个可以在Android系统上运行的二进制文件;

2) 写一个 hello.c 的测试用的C程序 ,并且把它编译成可执行文件;

3)把可执行文件上传到Android系统中,及一些注意事项。

4)写一个Java的UI程序来调用这个测试的C程序。



第一步  搭建坏境

主要参考了上面两个链接中的文章,简单而非常有帮助。

这里需要交叉编译的主要原因是Android系统源于Linux但不同于Linux,Linux上的程序无法直接在Android上运行。需要重新编译才行。Android设备主要基于 ARM的,在PC上的程序基于的X86的结构,这也导致了Linux下的程序必须重新编译才能在Android下运行。

在两篇文章中都提到了使用一个编译工具

arm-none-linux-gnueabi

一个使用的是 2009 版本的,一个是2008版本的。

配置方式都是把目标压缩文件Copy到一Linux的系统上,然后解压缩,设置PATH,

使用arm-none-linux-gnueabi-gcc 命令编译程序。

这里保存一下两个工具的下载地址

arm-2010.09-50-arm-none-linux-gnueabi

arm-2008q3-41-arm-none-linux-gnueabi


在Linux配置 PATH的方法 (Ubuntu)

1)  su nano ~/.bashrc

2)  在文件末尾添加如下的一行

export PATH=$PATH:/... .../... .../arm-2010.09-50/bin

3)  保存文件并退出

4)  运行命令 source ~/.bashrc

5)  当然可以用命令行验证一下是否成功  arm-none-linux-gnueabi-gcc  --version。



第二步  编译C程序

写一个简单的HelloWorld.c 的程序(最爱)。

#include int main(){  int i=0;  printf("hi ym012 %d/n",i);  return;}

使用命令  arm-none-linux-gnueabi-gcc - static HelloWorld.c -o HelloWorld

这里注意使用 -static 选项,测试时我没有使用这个参数,结果编译出来的程序在Android系统中是没法运行的。



第三步  上传C的可执行文件

把编译好的HelloWorld程序使用 adb push 上传的一个Android系统中。这里测试时使用的是一个Android虚拟机,其中虚拟了一个 256M的sdcard。这里把程序先上传到sdcard有一个好处是基本不会失败。

上传程序后当然可以尝试着在Android Shell 中运行编译好的程序。

1)  使用 adb shell, 进入Android 的命令行。

2)  cd /mnt/sdcard 进入HelloWorld的存储位置。

3)  ./HelloWorld 执行程序,


但如果尝试在sdcard 中运行程序多半会遇到一个Permision Denied一个错误。

我们可以简单尝试使用 chmod 777 HelloWorld来修复它,但再次运行程序时多半还会失败。

网上找了找原因,给出的解释是Android不能修改 sdcard下 程序的权限,最简单的老老实实把它复制到Android系统下的某个文件夹下吧。


4)  cp /mnt/sdcard/HelloWorld  /data/    复制文件到Android的data目录下

5)  chmod 777 HelloWorld  修改权限

6)  ls -l 当然可以在查询一下,但也不是必须的。

7)  ./HelloWorld  运行程序


这时基本已经可以了。


如果交叉编译出来的程序不正确在这里是没法运行的,出现 error:  magic 7F45  基本上就是交叉编译出的问题了。



第四步  使用Java 开发 UI

能在Android系统下把编译好的C程序运行起来基本已经完成了 90%了,这里使用Java 写一个Android的 UI 只是为了让程序更好玩一些。
这里主要使用的是 Progress 和 ProgressBuilder 的Java 的类库。


程序实例:

MainActivity.java

package com.example.systeminformation;import java.io.IOException;import android.os.Bundle;import android.app.Activity;import android.app.AlertDialog;import android.content.Intent;import android.view.View;import android.widget.Button;public class MainActivity extends Activity {private Button btnRunHello;private Intent intent;@Overrideprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btnRunHello = (Button) findViewById(R.id.id_run_hello);                btnRunHello.setOnClickListener(new View.OnClickListener()         {        @Override        public void onClick(View arg0)         {        CMDExecute m_Executor = new CMDExecute();               String m_strResult = "";    String arg[] = {"/data/hello"};    try     {m_strResult = m_Executor.run(arg, "/data");}     catch (IOException e)     {e.printStackTrace();}        new AlertDialog.Builder(MainActivity.this)     .setTitle("Run Hello")      .setMessage(m_strResult)     .setPositiveButton("确定", null)     .show();                }        });}}


CMDExecute,java

package com.example.systeminformation;import java.io.File;import java.io.IOException;import java.io.InputStream;public class CMDExecute {    public synchronized String run(String[] cmd, String workdirectory) throws IOException    {    String result = "";        try    {    ProcessBuilder builder = new ProcessBuilder(cmd);    if (workdirectory != null)    {    builder.directory(new File(workdirectory));    builder.redirectErrorStream(true);        Process process = builder.start();    InputStream in = process.getInputStream();    byte[] re = new byte[1024];        while (in.read(re) != -1)    {    System.out.println(new String (re));    result = result + new String(re);    }    in.close();    }    }    catch(Exception ex)    {    ex.printStackTrace();    }        return result;        }}


运行结果: 





更多相关文章

  1. 箭头函数的基础使用
  2. NPM 和webpack 的基础使用
  3. Python list sort方法的具体使用
  4. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  5. android 使用html5作布局文件: webview跟javascript交互
  6. Android(安卓)Resource介绍和使用
  7. "Failed to fetch URL https://dl-ssl.google.com/android/repos
  8. 使用NetBeans搭建Android开发环境
  9. android ndk编译x264开源(用于android的ffmpeg中进行软编码)

随机推荐

  1. 手把手带你搭建 Elasticsearch 集群
  2. Android采用PULL解析XML文档
  3. 关于android AppWidget初探①
  4. Android 菜单(SubMenu)
  5. 如何去除Android布局文件xml中的斜体样式
  6. Android ListView的背景和黑色边缘化的问
  7. [ant]通过Android命令自动编译出build.xm
  8. 使用风格化Android的GridView元素背景
  9. 在Android上有类似于session的东西,叫做Ap
  10. Android 4.4 KitKat 新特性