原文网址:http://www.linuxidc.com/Linux/2011-08/40901.htm

众所周知, NDK可以生成lib,让java程序通过jni来调用,其实,NDK也可以生成C/C++的可执行程序.不过这个程序要被执行的话还有要求.

1.可执行文件的名字必须是lib*.so. 否则apk安装时不会安装上去,因为目前apk的安装只支持安装lib文件,即lib*.so文件,如果不是此文件格式的,安装时不会拷到lib目录里.也可以考虑把可执行文件放assets里,java程序运行后把它拷贝到其它目录或系统目录.

2.这个文件的执行必须由java程序通过Runtime.getRuntime().exec()来执行.

下面来看看代码.

test.c 可以将此文件放在Android项目的jni目录里,需要自己创建jni目录,与res,src等目录同级.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    FILE *fp1;
    char ch;
    sleep(10);  // sleep 10 second
    if ((fp1 = fopen("textc.txt", "w")) == NULL)
    {
        printf("open file failed");
        exit(0);
    }

fprintf(fp1, "test string1");
    fclose(fp1);
    return 0;
}

再看看makefile文件.与test.c在同一目录
Android.mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= test.c

LOCAL_MODULE:= test

LOCAL_FORCE_STATIC_EXECUTABLE := true

LOCAL_STATIC_LIBRARIES := libc

LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := debug

include $(BUILD_EXECUTABLE)

注意上面的makefile,与生成lib的差别就是最后以行include $(BUILD_EXECUTABLE),这个是生成可执行文件的关键.

android项目代码,android项目是一个简单的例子,其中只有一个textview,将其id设为textView01.只有一个Activity:

package com.nicebooks.naviteexec;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MyActivity extends Activity {
    TextView mTextView01;

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mTextView01 = (TextView) findViewById(R.id.textView01);
        String path = "/data/data/" + getPackageName();
        String cmd1 = path + "/lib/libtest.so";
        String cmd2 = path + "/test";
        String cmd3 = "chmod 777 " + cmd2;
        String cmd4 = "dd if=" + cmd1 + " of=" + cmd2;
        RootCommand(cmd4);               //拷贝lib/libtest.so到上一层目录,同时命名为test.
        RootCommand(cmd3);               //改变test的属性,让其变为可执行
        RootCommand(cmd2);               //执行test程序.
    }

public boolean RootCommand(String command) {
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("sh");  //获得shell.
            DataInputStream inputStream = new DataInputStream(process.getInputStream());
            DataOutputStream outputStream = new DataOutputStream(process.getOutputStream());

outputStream.writeBytes(cd /data/data/" + getPackageName() + "\n");   //保证在command在自己的数据目录里执行,才有权限写文件到当前目录

outputStream.writeBytes(command + " &\n"); //让程序在后台运行,前台马上返回
            outputStream.writeBytes("exit\n");
            outputStream.flush();
            process.waitFor();
            
            byte[] buffer = new byte[inputStream.available()];
            inputStream.read(buffer);
            String s = new String(buffer);
            mTextView01.setText("CMD Result:\n" + s);
        } catch (Exception e) {
            mTextView01.setText("Exception:"+ e.getMessage());
            return false;
        }
        return true;
    }
}
看看layout文件

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:id="@+id/textView01"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
</LinearLayout>

下面开始build, 关于cygwin和NDK的环境这篇文章就不再讲,大家可以去google一下.

1.进入cygwin,cd到android项目的jni的路径,输入ndk-build,如果不出错,将在android项目里生成一个libs目录.libs目录还生成一个armeabi.在armeabi目录里会有一个test文件.

2.我们要将test文件改名成libtest.so.

3.然后在eclipse里clean/build.

4.将程序在手机上运行.可以看到 程序自己的数据目录下生成一个textc.txt文件.

而且即使java程序退出了,此test程序仍在执行,因为我用sleep和后台执行方式来执行的.test已经是一个独立的进程在android系统里运行了.

如果手机是破解的,有root权限的,可以将process = Runtime.getRuntime().exec("su");来替换上面同一行程序.这样你可以随意写文件到root能操作的目录,也可以执行其它root才能执行的命令.

全文完.

【转】使用NDK生成native C/C++的可执行程序的更多相关文章

  1. Android NDK生成共享库和静态库

    Date: 2014-03-14 Title: Compile Android Native Binary And Library Published: true Type: post Tags: A ...

  2. Linux Ubuntu下用Android NDK 生成独立交叉编译链

    本文主要介绍使用Android NDK生成独立交叉编译链,然后使用独立交叉编译链编译Android程序 下载NDK 下载与自己操作系统相吻合的版本 下载地址 解压到安装目录(如~/myndk): ta ...

  3. 如何在Eclipse中生成Native类对应的JNI的.h文件

    1 致谢 感谢super_level网友 他的博客写的很清楚 给了我很多帮助 链接如下:http://blog.csdn.net/super_level/article/details/2124353 ...

  4. android NDK 生成so 文件流程-ecplice

    1:生成jni目录 首先说一句网上,大部分博客这么写的:打开控制台,进入项目目录,运行javah -classpath bin/classes -d jni com.example.hellojni. ...

  5. 【Android Studio安装部署系列】二十五、Android studio使用NDK生成so文件和arr文件

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 Android Studio使用ndk的简单步骤. NDK环境搭建 下载NDK 下载链接:https://developer.and ...

  6. 用NDK生成so给第三方用

    参考了https://blog.csdn.net/zi413293813/article/details/50074239 然后自己重新整理补充 我用的ndk-r10d ndk下载地址http://d ...

  7. Ngen生成Native代码实战及优缺点分析

    先科普一下,.Net是一个用于Windows的托管代码模型,用于高效构建具有视觉上引人注目的用户体验的应用程序.但这个模型生成的代码并非可执行代码,而是由.Net公共语言运行库环境执行的IL代码.所以 ...

  8. Android NDK生成及连接静态库与动态库

    对于Android应用开发,大部分情况下我们使用Java就能完整地实现一个应用.但是在某些情况下,我们需要借助C/C++来写JNI本地代码.比如,在使用跨平台的第三方库的时候:为了提升密集计算性能的时 ...

  9. 用NDK生成cURL和OpenSSL库

    最近在用Qt开发Android应用时需要获取https页面内容,但Qt内置的QNetworkAccessManager类只支持下面这些协议(调用其supportedSchemes成员函数获取): (& ...

随机推荐

  1. go语言使用redis —— redigo

    redis的client有好多好多,go语言的client在redis官方有两个推荐,radix和redigo.选择哪一个好呢?确实很纠结,后来掷硬币决定选择redigo了. redis.go.red ...

  2. php如何查找会员无限分类的所有上级和所有下级

    a推广出的a-1,a-2继续推广,得到a-1-1,a-1-2等等数据库设计思路如下:用户表中有一个son这么一个字段,这个字段中存放名下所有会员的id,用分号隔开.这个字段的维护:比如a-1-1推广出 ...

  3. 1024: [SCOI2009]生日快乐 - BZOJ

    Description windy的生日到了,为了庆祝生日,他的朋友们帮他买了一个边长分别为 X 和 Y 的矩形蛋糕.现在包括windy,一共有 N 个人来分这块大蛋糕,要求每个人必须获得相同面积的蛋 ...

  4. javascript中跨源资源共享

    来自<javascript高级程序设计 第三版:作者Nicholas C. Zakas>的学习笔记(十) 通过XHR实现Ajax通信的一个主要限制,来源于跨域安全策略.默认情况下,XHR对 ...

  5. SQL手工注入

    site:xx.cn  inurl:asp?id= //找文章 xx.cn/pth/onews.asp?id=243' //试注入 xx.cn/pth/onews.asp?id=243 order b ...

  6. 线程以及数据对象的wait()和notifyAll()方法

    正在运行的程序称作一个进程,一个进程可以包含多个线程,这些线程可以共享进程的资源,它们共用一块存储空间.那么,各个线程在访问同一个数据对象的同时,可能引起冲突,以生产者.消费者为例,就会出现队列中没有 ...

  7. 1961-计算机基础知识大赛 2 (new)

    描述 求A^B的最后三位数表示的整数(1<=A,B<=10000) 输入 A B 输出 A^B的最后三位数 样例输入 2 3 12 6 样例输出 8 984 #include<ios ...

  8. 修改MYSQL数据库表的字符集

    MySQL 乱码的根源是的 MySQL 字符集设置不当的问题,本文汇总了有关查看 MySQL 字符集的命令.包括查看 MySQL 数据库服务器字符集.查看 MySQL 数据库字符集,以及数据表和字段的 ...

  9. IText PdfPTable表格 单元的居中显示

    昨晚寻找了网上很多关于IText表格居中问题,他们其中的有些代码我即使复制上去生成的doc表格的文字都是不居中的,后来我自己找出了一种居中方式: 为PdfPCell对象添加paragraph对象,并将 ...

  10. SaaS系列介绍之五: 我国SaaS市场分析

    1 我国SaaS市场现状 我国SaaS从ASP年代发展到今天,也有不少时间了.我国是个十几亿人的大国,国情复杂,各地贫富不均,发展不平衡.信息系统建设也是各树一帜,各地为王.特别是占有大量用户的中小企 ...