本文共 6711 字,大约阅读时间需要 22 分钟。
最近做了一些关于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。在本例子中前两种方法都有实现,至于第三种我相信地球人都知道。 [url]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[/url]转载地址:http://iyhci.baihongyu.com/