最近做了一些关于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

更多相关文章

  1. Android SQLite使用方法
  2. 用VS2010开发Android应用的配置方法
  3. 在Android程序中使用全局变量
  4. Activity对象的onCreate方法真是Android程序的入口吗?
  5. Android实现无标题栏全屏的方法
  6. 用git下载Android的某个应用程序

随机推荐

  1. OPhone开发环境设置
  2. Android之wifi篇
  3. AutoCompleteTextView 点击软键盘“下一
  4. Drawable和Bitmap
  5. Android(安卓)ndk获取手机内部存储卡的根
  6. Android(安卓)动态获取权限(6.0 , 7.0)
  7. 关于Android Studio如何更改初始布局排版
  8. Android(安卓)kotlin:json自动生成bean
  9. MediaRecorder音视频框架
  10. Android(安卓)Device Monitor结构和用法