在Android上运行的二进制adb 运行可执行文件件不能棉花糖问题,怎么解决

当前位置:
> 帖子正文
分享一个android上面运行二进制文件
打字太累,直接贴图,
什么是golang,编译出来就是直接的二进制文件。不同于apk的java,执行效率很高。golang的资源也很丰富。有编程基础的可以看看
不吐不快,我来说两句...
暂时没有回复
您需要注册登录后,才能回帖哦!
上市时间:2017.09
上市时间:2017.09
上市时间:2017.10
上市时间:2017.09
上市时间:2017.10
上市时间:2017.09
上市时间:2017.09
上市时间:2017.09
上市时间:2017.09
上市时间:2017.10君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
基于Android+NDK的智能灯光系统的设计与实现
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口在 Android 中调用二进制可执行程序(native executable ) - qingchen1984 - 博客园
随笔 - 236, 文章 - 0, 评论 - 3, 引用 - 0
前几天有需要在java代码中调用二进制程序,就在网上找了些资料,写点东西记录下。
& 也是基于linux 的,当然也可以运行二进制的可执行文件。只不过Android 限制了直接的方式只能安装运行apk文件。虽然有NDK可以用动态链接库的方式来用C的二进制代码,但毕竟不方便。至少我们可以调用linux的一些基本命令,如ls,rm等。
第一种方法:Runtime.exec(String[] args)
&&这种方法是java语言本身来提供的,在Android里面也可以使用。args是要执行的参数数组。大概用法如下:
&String[] args = new String[2];
&args[0] = "ls";
&args[1] = "-l";
&try&{&&Process process = Runtime.getRuntime().exec(arg);
&&//get the err line
&&InputStream stderr = process.getErrorStream();&&InputStreamReader isrerr = new InputStreamReader(stderr);&&BufferedReader brerr = new BufferedReader(isrerr);
&&//get the output line&&InputStream outs = process.getInputStream();&&InputStreamReader isrout = new InputStreamReader(outs);&&BufferedReader brout = new BufferedReader(isrout);
&&String errline =
&&String result = "";
&&// get the whole error message string&&while ( (line = brerr.readLine()) != null)&&{&&&result +=&&&result += "/n";
&&if( result != "" )
&&&// put the result string on the screen
&&// get the whole standard output string
&&while ( (line = brout.readLine()) != null)&&{&&&result +=&&&result += "/n";&&}&&if( result != "" )&&{
&&&// put the result string on the screen
&}catch(Throwable t)&{&&t.printStackTrace();&}
&以上代码执行了linux的标准命令 ls -l。执行此命令后的标准输出是在brout中。如果出错,像参数错误,命令错误等信息就会放在brerr中。
有需要的话从里面读出来便可。
第二种方法:Class.forName("android.os.Exec")
代码大概是这样:
&&// 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, "/system/bin/ls", "/sdcard", null, 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 { &S &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]); & } catch( ... )...&这种方法是用了 Android 提供的android.os.Exec类。在 Android 的源代码中已经提供了类似 terminal 的ap,在
/development/apps/Term/src/com/android/term 中,这个ap就是用android.os.Exec来调用linux的基本命令的。不过这个类只有在Android的内置ap中才可以使用。单独写一个非内置ap的话是无法直接调用android.os.Exec的。间接的方法就是类似上面,用Class.forName("android.os.Exec")来得到这个类,execClass.getMethod("createSubprocess", ... )来得到类里面的方法,这样就可以使用本来不能用的类了。这就是反射?...
&这个方法看起来要麻烦一些,而且比较歪,我觉得还是用java本身提供的东西比较好,毕竟简单,移植性也好点。
&至于自己写的二进制执行程序如何放到apk里面如何调用,原帖也说的很清楚,不过要提醒一下,assets文件夹对单个文件大小有限制为1MB. 所以如果有资源文件大于1MB我看只好自己先切割一下了,运行的时候再自己拼起来...Android 上实现非root的 Traceroute -- 非Root权限下移植可执行二进制文件 脚本文件
1. 原理思路
文件权限修改无法实现 : 如果 没有 root 权限, 就不能改变二进制文件的文件权限;
-- 将busybox推送到中 : 使用 adb push 命令, 将 busybox 传入到 sd 卡中, 注意, 上传到内存中无法实现;
-- 上传到sd卡成功 : 使用 adb push 文件名 手机中的文件全路径名 命令;
octopus@octopus:~/csdn$ adb push busybox-armv7l /sdcard/octopus/busybox
3256 KB/s (1109128 bytes in 0.332s)
-- 上传到内存失败 : 使用 adb push 上传到内存中失败, 因为 adb 使用的是 system 用户, 只有 root 用户才有权限向内存中写入数据;
octopus@octopus:~/csdn$ adb push busybox-armv7l /data/busybox
failed to copy 'busybox-armv7l' to '/data/busybox': Permission denied
-- 查看并修改busybox权限失败 : system 用户没有修改 sd 卡文件模式的权限;
shell@android:/sdcard/octopus $ ll
-rw-rw-r-- root
4-07-08 19:49 busybox
shell@android:/sdcard/octopus $ chmod 755 busybox
Unable to chmod busybox: Operation not permitted
应用程序解决方案 :
-- 应用程序专属用户 : Android 操作系统会为每个应用程序设置一个用户, 这个用户对其安装目录(/data/data/包名/)下的文件有完整的权限;
-- 将可执行二进制文件拷贝到安装目录中 : 将交叉编译好的 busybox 放到 工程目录下的 res/assets/ 目录下;
2. 实现策略
文件初始放置 : 将 交叉编译好的 busybox 文件放在 工程目录的 /res/assets/ 目录下;
文件拷贝 : 将该 二进制文件 拷贝到 app 的安装目录的 files 目录下, 即 /data/data/包名/files/下;
修改文件权限 : 使用命令可以直接修改该目录下的权限, 注意这个操作是可以执行的;
执行busybox : 在代码中执行 ./data/data/包名/files/
获取执行结果 :
3. 使用到的api解析
(1) 获取 assets 目录文件的输入流
InputStream is = context.getAssets().open(source);
-- 获取AssetsManager : 调用 Context 上下文对象的 context.getAssets() 即可获取 AssetsManager对象;
-- 获取输入流 : 调用 AssetsManager 的 open(String fileName) 即可获取对应文件名的输入流;
(2) 文件流相关操作
根据输入流获取文件大小 : 调用输入流的 inputStream.available() 方法;
int size = is.available();
将文件读取到缓冲区中 : 创建一个与文件大小相同的字节数组缓冲区, 输入流将数据存放到缓冲区中;
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
将文件写到内存中 : 调用上下文对象的 openFileOutput(绝对路径名, 权限), 即可创建一个文件的输出流;
FileOutputStream output = context.openFileOutput(destination, Context.MODE_PRIVATE);
output.write(buffer);
output.close();
(3) 获取文件的绝对路径
获取app绝对安装路径 : 调用 上下文对象的 getFilesDir().getAbsolutePath() 方法;
String filesPath = context.getFilesDir().getAbsolutePath();
(4) 执行二进制文件
创建 Process 对象, 并使用该 process 执行shell脚本命令 :
Runtime runtime = Runtime.getRuntime();
process = runtime.exec(cmd);
获取执行的命令行结果 :
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line =
while ((line = br.readLine()) != null) {
processList.add(line);
br.close();
4. 代码示例
MainActivity 主程序代码 :
package cn.org.octopus.
import java.io.BufferedR
import java.io.FileNotFoundE
import java.io.FileOutputS
import java.io.IOE
import java.io.InputS
import java.io.InputStreamR
import java.util.ArrayL
import java.util.L
import android.content.C
import android.os.B
import android.support.v7.app.ActionBarA
import android.view.V
import android.widget.EditT
import android.widget.TextV
/** 看不懂注释我就吃半斤狗粮 :-) */
public class MainActivity extends ActionBarActivity {
private EditText et_
private String app_
private TextView tv_
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity);
/*初始化控件*/
et_cmd = (EditText) findViewById(R.id.et_cmd);
tv_result = (TextView) findViewById(R.id.tv_result);
/* 获取app安装路径 */
app_path = getApplicationContext().getFilesDir().getAbsolutePath();
/** 按钮点击事件 */
public void onClick(View view) {
int id = view.getId();
switch (id) {
case R.id.copy_busybox: /* 拷贝busybox可执行文件 */
varifyFile(getApplicationContext(), busybox);
case R.id.copy_traceroute:/* 拷贝traceroute可执行文件 */
varifyFile(getApplicationContext(), traceroute);
case R.id.exe_busybox:/* 将busybox命令添加到Editext中 */
String cmd = . + app_path + /
System.out.println(et_cmd);
et_cmd.setText(cmd);
case R.id.exe_traceroute:/* 将traceroute命令添加到Editext中 */
cmd = . + app_path + /traceroute 8.8.8.8;
et_cmd.setText(cmd);
case R.id.exe: /* 执行Editext中的命令 */
cmd = et_cmd.getText().toString();
/* 执行脚本命令 */
List results = exe(cmd);
String result = ;
/* 将结果转换成字符串, 输出到 TextView中 */
for(String line : results){
result += line +
tv_result.setText(result);
/** 验证文件是否存在, 如果不存在就拷贝 */
private void varifyFile(Context context, String fileName) {
/* 查看文件是否存在, 如果不存在就会走异常中的代码 */
context.openFileInput(fileName);
} catch (FileNotFoundException notfoundE) {
/* 拷贝文件到app安装目录的files目录下 */
copyFromAssets(context, fileName, fileName);
/* 修改文件权限脚本 */
String script = chmod 700
+ app_path + / + fileN
/* 执行脚本 */
exe(script);
} catch (Exception e) {
e.printStackTrace();
/** 将文件从assets目录中拷贝到app安装目录的files目录下 */
private void copyFromAssets(Context context, String source,
String destination) throws IOException {
/* 获取assets目录下文件的输入流 */
InputStream is = context.getAssets().open(source);
/* 获取文件大小 */
int size = is.available();
/* 创建文件的缓冲区 */
byte[] buffer = new byte[size];
/* 将文件读取到缓冲区中 */
is.read(buffer);
/* 关闭输入流 */
is.close();
/* 打开app安装目录文件的输出流 */
FileOutputStream output = context.openFileOutput(destination,
Context.MODE_PRIVATE);
/* 将文件从缓冲区中写出到内存中 */
output.write(buffer);
/* 关闭输出流 */
output.close();
/** 执行 shell 脚本命令 */
private List exe(String cmd) {
/* 获取执行工具 */
Process process =
/* 存放脚本执行结果 */
List list = new ArrayList();
/* 获取运行时环境 */
Runtime runtime = Runtime.getRuntime();
/* 执行脚本 */
process = runtime.exec(cmd);
/* 获取脚本结果的输入流 */
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line =
/* 逐行读取脚本执行结果 */
while ((line = br.readLine()) != null) {
list.add(line);
br.close();
} catch (IOException e) {
e.printStackTrace();
home_activity.xml 布局文件代码 :
5. 执行结果
执行 busybox 程序 :
执行 traceroute 程序 :
示例代码下载 :
-- CSDN : https://download.csdn.net/detail/han9253;
-- GitHub : /han1202012/TracerouteAndB
作者 : 万境绝尘
转载请著名出处 : https://blog.csdn.net/shulianghan/article/details/下次自动登录
现在的位置:
& 综合 & 正文
在 Android 中调用二进制可执行程序(native executable )– 在代码中执行shell命令
前几天有需要在java代码中调用二进制程序,就在网上找了些资料,写点东西记录下。
Android 也是基于linux 的系统,当然也可以运行二进制的可执行文件。只不过Android 限制了直接的方式只能安装运行apk文件。虽然有NDK可以用动态链接库的方式来用C的二进制代码,但毕竟不方便。至少我们可以调用linux的一些基本命令,如ls,rm等。
第一种方法:Runtime.exec(String[] args)
这种方法是java语言本身来提供的,在Android里面也可以使用。args是要执行的参数数组。大概用法如下:
String[] args = new String[2];
args[0] = "ls";
args[1] = "-l";
Process process = Runtime.getRuntime().exec(arg);
//get the err line
InputStream stderr = process.getErrorStream();
InputStreamReader isrerr = new InputStreamReader(stderr);
BufferedReader brerr = new BufferedReader(isrerr);
//get the output line
InputStream outs = process.getInputStream();
InputStreamReader isrout = new InputStreamReader(outs);
BufferedReader brout = new BufferedReader(isrout);
String errline =
String result = "";
// get the whole error message string
while ( (line = brerr.readLine()) != null)
result += "/n";
if( result != "" )
// put the result string on the screen
// get the whole standard output string
while ( (line = brout.readLine()) != null)
result += "/n";
if( result != "" )
// put the result string on the screen
}catch(Throwable t) {
t.printStackTrace(); }
以上代码执行了linux的标准命令 ls -l。执行此命令后的标准输出是在brout中。如果出错,像参数错误,命令错误等信息就会放在brerr中。
有需要的话从里面读出来便可。
第二种方法:Class.forName("android.os.Exec")
这个方法是一个老外找到的,原贴在这里:
代码大概是这样:
// 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, "/system/bin/ls", "/sdcard", null, 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 = "";
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]);
} catch( ... )... 这种方法是用了 Android 提供的android.os.Exec类。在 Android 的源代码中已经提供了类似 terminal 的ap,在
/development/apps/Term/src/com/android/term 中,这个ap就是用android.os.Exec来调用linux的基本命令的。不过这个类只有在Android的内置ap中才可以使用。单独写一个非内置ap的话是无法直接调用android.os.Exec的。间接的方法就是类似上面,用Class.forName("android.os.Exec")来得到这个类,execClass.getMethod("createSubprocess", ... )来得到类里面的方法,这样就可以使用本来不能用的类了。这就是反射?...
这个方法看起来要麻烦一些,而且比较歪,我觉得还是用java本身提供的东西比较好,毕竟简单,移植性也好点。
至于自己写的二进制执行程序如何放到apk里面如何调用,原帖也说的很清楚,不过要提醒一下,assets文件夹对单个文件大小有限制为1MB. 所以如果有资源文件大于1MB我看只好自己先切割一下了,运行的时候再自己拼起来...
本文来自CSDN博客,转载请标明出处:
&&&&推荐文章:
【上篇】【下篇】

我要回帖

更多关于 centos运行可执行文件 的文章

 

随机推荐