原文网址: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. 几种解析xml方式的比较

    1: DOM DOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准.DOM 是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在树中寻找特定信息.分析该结构通常需要加 ...

  2. Oracle分析函数 — sum, rollup, cube, grouping用法

    本文通过例子展示sum, rollup, cube, grouping的用法. //首先建score表 create table score( class  nvarchar2(20), course ...

  3. MySQL --log-slave-updates

     官方说明:--log-slave-updates Command-Line Format --log-slave-updates Option-File Format log-slave-updat ...

  4. angularApi网站用vue重构

    最近在博客园上看到不少关于vue的文章但感觉都是在简单原生写法上,真正vue在实际开发中的优点组件化,spa应用,路由好像都没涉及到,我在学angular1的时候发现没有中文版的api,于是本人不才弄 ...

  5. AOP和IOC个人理解

    14:18 2014/5/5 IOC inversion of control 控制反转  将new对象的权力由调用者转移到spring容器(即xml文件),Struts2与Spring整合(scop ...

  6. oc 中四种实例变量的范围类型@private@protected@public@package

    To enforce the ability of an object to hide its data, the compiler limits the scope of instance vari ...

  7. 归档 NSKeyedArchiver

    复杂对象无法象 NSString,NSArray等简单对象一样直接通过 writeToFile 实现持久化,当对复杂对象进行持久化时需要将其转化为 NSData (归档),但获取数据时,将 NSDat ...

  8. ASP + ACCESS 上传图片到数据库与将图片读出数据库显示之实现

    1.uppic.asp:上传图片程序 <% dim rs dim formsize,formdata,bncrlf,divider,datastart,dataend,mydata formsi ...

  9. Manifest 与TypeTag

    Manifest和TypeTag是要解决什么问题?   As with other JVM languages, Scala’s types are erased at compile time. T ...

  10. pthread_create用法

    linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread. #include <pthread.h> int pthread_create(pth ...