原文网址: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. Battle Over Cities (25)(DFS、连通图)

    It is vitally important to have all the cities connected by highways in a war. If a city is occupied ...

  2. 【socket】Socket的三个功能类TCPClient、TCPListener 和 UDPClient

    Socket的三个功能类TCPClient.TCPListener 和 UDPClient (转) 应用程序可以通过 TCPClient.TCPListener 和 UDPClient 类使用传输控制 ...

  3. 进程、线程、GDI+、XML、委托

    进制 表示某一位置上的数运算时是逢X进一位.二进制就是逢二进一, 十进制是逢十进一,十六进制是逢十六进一,以此类推. so:二进制001010101只有0和1计算机中的数据都是二进制表示,四进制以0. ...

  4. The ‘Microsoft.ACE.OLEDB.12.0′ provider is not registered on the local machine. (System.Data)

    When you try to import Excel 2007 or later “.xlsx” files into an SQL Server 2008 database you may ge ...

  5. UINavigationBar导航栏相关设置

    设置导航颜色 [[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1] ...

  6. vs中使用过的扩展和好的nuget库

    扩展 ReAttach ReAttach gives you an easy way to ReAttaching your prior debug targets. ReAttach stores ...

  7. iis7、mvc2.0 文件上传配置方案

    http://blog.csdn.net/useruse/article/details/5602495

  8. [转载]再次谈谈easyui datagrid 的数据加载

    这篇文章只谈jQuery easyui datagrid 的数据加载,因为这也是大家谈论最多的内容.其实easyui datagrid加载数据只有两种方式:一种是ajax加载目标url返回的json数 ...

  9. 设置UINavigation的背景图片和背景颜色

    //通过背景图片来设置背景 float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; UIImage * ...

  10. live555源码研究(四)------UserAuthenticationDatabase类

    一.UserAuthenticationDatabase类作用 1,用户/密码管理 2,鉴权管理 二.类UserAuthenticationDatabase继承关系图                 ...