`
sharp2wing
  • 浏览: 271105 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

在android上运行native可执行程序

阅读更多
最近做了一些关于Android Native 编程相关的东西,在这篇文章中我将介绍如何在Android application中调用Native executable。至于如何编写Native executable和如何打包native到apk中,之前我都有文章介绍这里就不再重复了。

我写了一个Demo程序,演示如何在Android Application中调用Native executable。该示例中:

    * 可以调用系统自带的executable,例如“/system/bin/ls”;
    * 可以调用自己编写的Native executable,放置在apk的assets目录下;
    * 可以调用从远程服务器下载的Native executable;

接下来详细介绍代码的实现,在这里我们主要用到了android.os.Exec,但是android.os.Exec不被包含在android.jar中,因此只能通过java反射机制来实现。

以下代码实现了一个通用的exec函数:
view plaincopy to clipboardprint?

   1. private String exec(String arg0, String arg1, String arg2) { 
   2.         try { 
   3.             // android.os.Exec is not included in android.jar so we need to use reflection. 
   4.             Class execClass = Class.forName("android.os.Exec"); 
   5.             Method createSubprocess = execClass.getMethod("createSubprocess", 
   6.                     String.class, String.class, String.class, int[].class); 
   7.             Method waitFor = execClass.getMethod("waitFor", int.class); 
   8.  
   9.             // Executes the command. 
  10.             // NOTE: createSubprocess() is asynchronous. 
  11.             int[] pid = new int[1]; 
  12.             FileDescriptor fd = (FileDescriptor)createSubprocess.invoke( 
  13.                     null, arg0, arg1, arg2, pid); 
  14.  
  15.             // Reads stdout. 
  16.             // NOTE: You can write to stdin of the command using new FileOutputStream(fd). 
  17.             FileInputStream in = new FileInputStream(fd); 
  18.             BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
  19.             String output = ""; 
  20.             try { 
  21.                 String line; 
  22.                 while ((line = reader.readLine()) != null) { 
  23.                     output += line + "\n"; 
  24.                 } 
  25.             } catch (IOException e) { 
  26.                 // It seems IOException is thrown when it reaches EOF. 
  27.             } 
  28.  
  29.             // Waits for the command to finish. 
  30.             waitFor.invoke(null, pid[0]); 
  31.  
  32.             return output; 
  33.         } catch (ClassNotFoundException e) { 
  34.             throw new RuntimeException(e.getMessage()); 
  35.         } catch (SecurityException e) { 
  36.             throw new RuntimeException(e.getMessage()); 
  37.         } catch (NoSuchMethodException e) { 
  38.             throw new RuntimeException(e.getMessage()); 
  39.         } catch (IllegalArgumentException e) { 
  40.             throw new RuntimeException(e.getMessage()); 
  41.         } catch (IllegalAccessException e) { 
  42.             throw new RuntimeException(e.getMessage()); 
  43.         } catch (InvocationTargetException e) { 
  44.             throw new RuntimeException(e.getMessage()); 
  45.         } 
  46.     } 

private String exec(String arg0, String arg1, String arg2) {
try {
// android.os.Exec is not included in android.jar so we need to use reflection.
Class execClass = Class.forName("android.os.Exec");
        Method createSubprocess = execClass.getMethod("createSubprocess",
        String.class, String.class, String.class, int[].class);
        Method waitFor = execClass.getMethod("waitFor", int.class);

        // Executes the command.
        // NOTE: createSubprocess() is asynchronous.
        int[] pid = new int[1];
        FileDescriptor fd = (FileDescriptor)createSubprocess.invoke(
        null, arg0, arg1, arg2, pid);

        // Reads stdout.
        // NOTE: You can write to stdin of the command using new FileOutputStream(fd).
        FileInputStream in = new FileInputStream(fd);
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String output = "";
        try {
        String line;
while ((line = reader.readLine()) != null) {
output += line + "\n";
}
} catch (IOException e) {
// It seems IOException is thrown when it reaches EOF.
}

// Waits for the command to finish.
waitFor.invoke(null, pid[0]);

return output;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e.getMessage());
} catch (SecurityException e) {
throw new RuntimeException(e.getMessage());
} catch (NoSuchMethodException e) {
throw new RuntimeException(e.getMessage());
} catch (IllegalArgumentException e) {
throw new RuntimeException(e.getMessage());
} catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage());
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getMessage());
}
    }

以下代码实现如何执行assets中的Native executable程序:
view plaincopy to clipboardprint?

   1. private int getassetsfile(String fileName, String tagFile) { 
   2.         int retVal = 0; 
   3.         try { 
   4.  
   5.             File dir = new File(tagFile); 
   6.             if (dir.exists()) { 
   7.                 dir.delete(); 
   8.             } 
   9.  
  10.             InputStream in = this.getAssets().open(fileName); 
  11.             if(in.available() == 0) { 
  12.                 return retVal; 
  13.             } 
  14.  
  15.             FileOutputStream out = new FileOutputStream(tagFile); 
  16.             int read; 
  17.             byte[] buffer = new byte[4096]; 
  18.             while ((read = in.read(buffer)) > 0) { 
  19.                 out.write(buffer, 0, read); 
  20.             } 
  21.             out.close(); 
  22.             in.close(); 
  23.  
  24.             retVal = 1; 
  25.             return retVal; 
  26.         } catch (IOException e) { 
  27.             throw new RuntimeException(e.getMessage()); 
  28.         } 
  29.     } 

private int getassetsfile(String fileName, String tagFile) {
    int retVal = 0;
    try {

    File dir = new File(tagFile);
if (dir.exists()) {
dir.delete();
}

    InputStream in = this.getAssets().open(fileName);
    if(in.available() == 0) {
    return retVal;
    }

    FileOutputStream out = new FileOutputStream(tagFile);
int read;
byte[] buffer = new byte[4096];
while ((read = in.read(buffer)) > 0) {
out.write(buffer, 0, read);
}
out.close();
in.close();

retVal = 1;
return retVal;
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
    }

以下代码实现如何执行远程服务器上的Native executable程序:
view plaincopy to clipboardprint?

   1. private void download(String urlStr, String localPath) { 
   2.         try { 
   3.             URL url = new URL(urlStr); 
   4.             HttpURLConnection urlconn = (HttpURLConnection)url.openConnection(); 
   5.             urlconn.setRequestMethod("GET"); 
   6.             urlconn.setInstanceFollowRedirects(true); 
   7.             urlconn.connect(); 
   8.             InputStream in = urlconn.getInputStream(); 
   9.             FileOutputStream out = new FileOutputStream(localPath); 
  10.             int read; 
  11.             byte[] buffer = new byte[4096]; 
  12.             while ((read = in.read(buffer)) > 0) { 
  13.                 out.write(buffer, 0, read); 
  14.             } 
  15.             out.close(); 
  16.             in.close(); 
  17.             urlconn.disconnect(); 
  18.         } catch (MalformedURLException e) { 
  19.             throw new RuntimeException(e.getMessage()); 
  20.         } catch (IOException e) { 
  21.             throw new RuntimeException(e.getMessage()); 
  22.         } 
  23.     } 

private void download(String urlStr, String localPath) {
    try {
URL url = new URL(urlStr);
HttpURLConnection urlconn = (HttpURLConnection)url.openConnection();
urlconn.setRequestMethod("GET");
urlconn.setInstanceFollowRedirects(true);
urlconn.connect();
InputStream in = urlconn.getInputStream();
FileOutputStream out = new FileOutputStream(localPath);
int read;
byte[] buffer = new byte[4096];
while ((read = in.read(buffer)) > 0) {
out.write(buffer, 0, read);
}
out.close();
in.close();
urlconn.disconnect();
} catch (MalformedURLException e) {
throw new RuntimeException(e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
    }

总结下:

通常有三种方法把Native executable放置到手机上:1.assets;2.via network;3.via pc use adb。在本例子中前两种方法都有实现,至于第三种我相信地球人都知道。

http://www.theiter.com/2010/05/%E5%9C%A8android%E4%B8%8A%E8%BF%90%E8%A1%8Cnative%E5%8F%AF%E6%89%A7%E8%A1%8C%E7%A8%8B%E5%BA%8F.html
分享到:
评论

相关推荐

    Android 加载执行ELF可执行文件

    在Android系统中,执行外部程序通常涉及到对二进制可执行文件(如ELF)的加载和运行。本文将深入探讨Android如何加载和执行ELF(Executable and Linkable Format)可执行文件,以及如何在Android应用中实现这一过程...

    ffmpeg6.2.2-库、头文件、可执行程序 for android

    压缩包中的可执行程序通常是为了便于测试和调试而提供的,可以在 Android 设备上直接运行。这些程序可能包含了一些预设的多媒体处理任务,如播放、转码或提取元数据。对于开发者来说,它们可以作为快速验证 FFmpeg ...

    hermes,hermes是一个小型的轻量级javascript引擎,为在android上运行react native而优化。.zip

    这些优化可以显著减少运行时的计算需求,使得应用程序运行更高效,尤其是在资源有限的移动设备上。 ** 压缩字节码 ** 不同于传统的JavaScript解释器,Hermes将JavaScript代码转换为压缩字节码。这种字节码格式比源...

    Android Native Exception

    在Android系统中,应用程序主要基于Java运行时环境进行开发,但也有不少部分是通过Native代码(如C/C++)实现的,这些Native代码通常运行在较低级别的操作系统层面上。当Native代码出现错误时,就会触发Native ...

    gdb动态调试android可执行程序1

    gdb动态调试Android可执行程序 标题:gdb动态调试Android可执行程序1 描述:gdb动态调试Android可执行程序1 标签:android 知识点: 1. Android NDK:Android NDK是一组工具集,允许开发者使用C++和其他native...

    nodejs V9 android arm64 版本,可执行程序,android系统内解压使用

    这个版本的Node.js是高度优化的,能够在Android系统的环境下执行JavaScript代码,支持本地应用程序开发和运行。Node.js是一个开放源码、跨平台的JavaScript运行环境,它让开发者可以在服务器端执行JavaScript,打破...

    android 实现让程序一直处于前台

    在Android开发中,保持应用程序始终处于前台运行是一个常见的需求,特别是在音乐播放器、导航应用或者后台服务等场景下。为了实现这一目标,开发者通常会利用服务(Service)和通知(Notification)来配合工作。以下...

    react native android 命令打包

    2. **生成JavaScript bundle文件**:此步骤用于将项目中的JavaScript代码打包成一个文件,便于在Android设备上运行。命令如下: ``` react-native bundle --platform android --dev false --entry-file index.js -...

    在Native层实现MediaCodec H264 编码.zip

    编译后的可执行程序可以在设备上运行,实时编码视频流,这对于测试和性能优化非常有帮助。 在实际应用中,Native层的MediaCodec H264编码常用于实时视频通信、视频录制等场景,对于提升性能、减少CPU负载有着显著...

    android NativeMethodHook

    在Android应用开发中,特别是在系统级或root级别的操作中,Native Method Hook是不可或缺的工具。 一、Native Method Hook的基本原理 Native Method Hook主要基于Android的JNI(Java Native Interface)机制,通过...

    android智能卡检测程序源码以及apk程序以及libpcsclite.so和libpcsclite.a,还包含android.mk文件

    "apk程序"是Android应用程序的打包格式,这里提供的apk文件是已经编译和打包好的智能卡检测程序,用户可以直接在Android设备上安装运行。通过反编译或使用调试工具,开发者可以进一步研究apk内部的工作机制。 ...

    react-native-background-task:跨平台(iOS和Android)的React Native应用程序的定期后台任务,即使关闭该应用程序也可以运行

    适用于跨平台(iOS和Android)的React Native应用程序的定期后台任务,即使关闭该应用程序也会运行这些任务。 该库允许安排单个定期任务,该任务在应用程序处于后台或关闭状态时执行,执行频率不超过每15分钟一次...

    简单易用的ReactNative截屏监听系统截屏事件组件iosandroid

    通过React Native,开发者可以编写一次代码,然后在多个平台上运行,极大地提高了开发效率和代码的可重用性。 在"react-native-screenshot"组件中,主要涉及以下几个核心概念和技术: 1. **事件监听**:组件的核心...

    Android 原生webApp的运行壳

    在Android开发中,原生WebApp的运行壳是一种技术手段,允许开发者将基于Web的应用程序(HTML、CSS、JavaScript)嵌入到一个Android应用中,从而实现与原生应用相似的用户体验。这种技术通常被称为Hybrid App开发,它...

    android C/C++程序

    再者,`ANDROID NDK实践开发系列--(01) 使用ndk编译c可执行程序`可能涉及了Android NDK(Native Development Kit)的基础知识。NDK是一组工具,允许开发者在Android平台上使用C和C++编写原生代码。该文章可能会...

    安卓可执行C代码

    标题"安卓可执行C代码"和标签"安卓C程序"暗示了我们将讨论如何在Android环境中运行C语言编写的代码。 Android NDK(Native Development Kit)为开发原生C/C++代码提供了支持。NDK是一组工具,允许开发者在Android...

    iconv库 android ndk可运行

    通过NDK,开发者可以利用iconv库这样的C/C++库在Android设备上实现高效、低级别的处理,尤其是在需要高性能计算或者调用硬件加速功能时。在Android中,iconv库通常会编译为共享对象库(.so文件),以便于Java代码...

    Android开发第一个ndk程序

    NDK提供了一种方式,让开发者可以在Android平台上编译和运行原生代码,而原生代码通常比Java代码运行得更快,因为它们直接与硬件交互。这在处理图形渲染、物理模拟、加密算法或者需要高性能计算的任务时特别有用。 ...

    linphone-android项目导入eclipse可直接运行20150403整理

    总的来说,"linphone-android项目导入Eclipse可直接运行20150403整理"提供了一个宝贵的学习和实践SIP通信技术的平台,对于想要在Android上实现VoIP功能的开发者来说,这是一个很好的起点。通过实际操作,不仅能学习...

Global site tag (gtag.js) - Google Analytics