最近做了一些关于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(Executable and Linkable Format)可执行文件,以及如何在Android应用中实现这一过程...
压缩包中的可执行程序通常是为了便于测试和调试而提供的,可以在 Android 设备上直接运行。这些程序可能包含了一些预设的多媒体处理任务,如播放、转码或提取元数据。对于开发者来说,它们可以作为快速验证 FFmpeg ...
这些优化可以显著减少运行时的计算需求,使得应用程序运行更高效,尤其是在资源有限的移动设备上。 ** 压缩字节码 ** 不同于传统的JavaScript解释器,Hermes将JavaScript代码转换为压缩字节码。这种字节码格式比源...
在Android系统中,应用程序主要基于Java运行时环境进行开发,但也有不少部分是通过Native代码(如C/C++)实现的,这些Native代码通常运行在较低级别的操作系统层面上。当Native代码出现错误时,就会触发Native ...
gdb动态调试Android可执行程序 标题:gdb动态调试Android可执行程序1 描述:gdb动态调试Android可执行程序1 标签:android 知识点: 1. Android NDK:Android NDK是一组工具集,允许开发者使用C++和其他native...
这个版本的Node.js是高度优化的,能够在Android系统的环境下执行JavaScript代码,支持本地应用程序开发和运行。Node.js是一个开放源码、跨平台的JavaScript运行环境,它让开发者可以在服务器端执行JavaScript,打破...
在Android开发中,保持应用程序始终处于前台运行是一个常见的需求,特别是在音乐播放器、导航应用或者后台服务等场景下。为了实现这一目标,开发者通常会利用服务(Service)和通知(Notification)来配合工作。以下...
2. **生成JavaScript bundle文件**:此步骤用于将项目中的JavaScript代码打包成一个文件,便于在Android设备上运行。命令如下: ``` react-native bundle --platform android --dev false --entry-file index.js -...
编译后的可执行程序可以在设备上运行,实时编码视频流,这对于测试和性能优化非常有帮助。 在实际应用中,Native层的MediaCodec H264编码常用于实时视频通信、视频录制等场景,对于提升性能、减少CPU负载有着显著...
在Android应用开发中,特别是在系统级或root级别的操作中,Native Method Hook是不可或缺的工具。 一、Native Method Hook的基本原理 Native Method Hook主要基于Android的JNI(Java Native Interface)机制,通过...
"apk程序"是Android应用程序的打包格式,这里提供的apk文件是已经编译和打包好的智能卡检测程序,用户可以直接在Android设备上安装运行。通过反编译或使用调试工具,开发者可以进一步研究apk内部的工作机制。 ...
适用于跨平台(iOS和Android)的React Native应用程序的定期后台任务,即使关闭该应用程序也会运行这些任务。 该库允许安排单个定期任务,该任务在应用程序处于后台或关闭状态时执行,执行频率不超过每15分钟一次...
通过React Native,开发者可以编写一次代码,然后在多个平台上运行,极大地提高了开发效率和代码的可重用性。 在"react-native-screenshot"组件中,主要涉及以下几个核心概念和技术: 1. **事件监听**:组件的核心...
在Android开发中,原生WebApp的运行壳是一种技术手段,允许开发者将基于Web的应用程序(HTML、CSS、JavaScript)嵌入到一个Android应用中,从而实现与原生应用相似的用户体验。这种技术通常被称为Hybrid App开发,它...
再者,`ANDROID NDK实践开发系列--(01) 使用ndk编译c可执行程序`可能涉及了Android NDK(Native Development Kit)的基础知识。NDK是一组工具,允许开发者在Android平台上使用C和C++编写原生代码。该文章可能会...
标题"安卓可执行C代码"和标签"安卓C程序"暗示了我们将讨论如何在Android环境中运行C语言编写的代码。 Android NDK(Native Development Kit)为开发原生C/C++代码提供了支持。NDK是一组工具,允许开发者在Android...
通过NDK,开发者可以利用iconv库这样的C/C++库在Android设备上实现高效、低级别的处理,尤其是在需要高性能计算或者调用硬件加速功能时。在Android中,iconv库通常会编译为共享对象库(.so文件),以便于Java代码...
NDK提供了一种方式,让开发者可以在Android平台上编译和运行原生代码,而原生代码通常比Java代码运行得更快,因为它们直接与硬件交互。这在处理图形渲染、物理模拟、加密算法或者需要高性能计算的任务时特别有用。 ...
总的来说,"linphone-android项目导入Eclipse可直接运行20150403整理"提供了一个宝贵的学习和实践SIP通信技术的平台,对于想要在Android上实现VoIP功能的开发者来说,这是一个很好的起点。通过实际操作,不仅能学习...