使用android studio编写一个简单的Android Linux终端


Android 系统的底层(核心)就是linux,它是基于Linux内核的操作系统,这意味着Android继承了Linux操作系统的许多特性和功能,如进程管理、内存管理、网络协议栈等等。Android通过在Linux内核之上添加硬件抽象层(Hardware Abstraction Layer)和Android运行时环境(Android Runtime Environment)等组件来实现应用程序开发的框架。

由于Android使用Linux内核,因此可以在Android设备上运行许多Linux命令和工具,知道这一点,下面就动手制作一个简单的Android应用程序示例,可以在界面上方输入Linux命令,并在下方回显命令结果。

1. 首先使用android studio创建新的Android项目,选择“新建项目”,填写相关信息即可。


2. 在项目的layout文件中新建一个布局,添加EditText和一个Button以及一个TextView,分别对应 输入框、运行按钮 和 回显文本。activity_main.xml代码如下:

<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
<EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="请输入Linux命令"
    android:padding="16dp"
    android:textSize="18sp"
    android:background="@drawable/edit_text_background"/>
<Button
    android:text="运行"
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="end"
    android:layout_margin="16dp"
    android:textSize="18sp"/>
<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:textSize="18sp"
    android:background="@drawable/text_view_background"/>
</LinearLayout>


3. 在MainActivity类中,使用Runtime.getRuntime().exec()方法执行Linux命令,并将命令输出结果显示在TextView中。具体操作如下:

public class MainActivity extends AppCompatActivity {
    private EditText editText;
    private Button button;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = findViewById(R.id.editText);
        button = findViewById(R.id.button);
        textView = findViewById(R.id.textView);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 请求权限
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                        requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                    }
                }
                // 获取命令输入
                String command = editText.getText().toString().trim();
                if (!command.isEmpty()) { // 检查命令是否为空
                    try {
                        Process process = Runtime.getRuntime().exec(command); //使用Runtime.getRuntime().exec()方法执行Linux命令
                        BufferedReader reader = new BufferedReader(
                                new InputStreamReader(process.getInputStream()));
                        StringBuilder output = new StringBuilder();
                        String line;
                        while ((line = reader.readLine()) != null) {
                            output.append(line + "\n");
                        }
                        // 执行命令并输出结果
                        textView.setText(output.toString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else { // 如果命令为空,则清空TextView
                    textView.setText("");
                }
            }
        });

    }
}

最后别忘记在AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


编译安装到手机或者模拟器中运行一下,就是这个样子:



是不是很简单,其实还是很多功能可以扩展的。这个示例主要是调用了JAVA的Runtime.getRuntime().exec()来实现的。

Runtime.getRuntime().exec()是Java的一个方法,用于在当前进程中启动一个新进程,并执行指定的命令。这个方法返回一个Process对象,用于控制新进程的执行。
exec()方法有多个重载版本,可以接受一个字符串参数或一个字符串数组参数。字符串参数指定要执行的命令,字符串数组参数则允许指定命令及其参数。

例如,以下代码将在当前进程中启动一个新进程,并执行Linux中的ls命令来列出当前目录下的文件和子目录:

Process process = Runtime.getRuntime().exec("ls");

另外一个例子,以下代码将启动一个新进程并执行Windows中的ping命令,并将其输出写入文件中:

Process process = Runtime.getRuntime().exec("cmd /c ping localhost > output.txt");

在Android应用程序中,Runtime.getRuntime().exec()通常用于执行一些需要调用底层系统命令的任务。例如,您可以使用它来执行一些shell命令,比如ps、top等,以监视和管理当前运行的进程。但需要注意的是,在使用exec()时,需要处理好进程的标准输入、标准输出和错误输出流,以避免产生意外的结果。

至于能执行哪些命令,取决于手机系统内核,如:在system/bin目录里面是否存在该命令二进制文件。如果手机root过可以自己添加所需的二进制进去或者通过第三方工具添加。

以上的示例主要是出于学习和试验的目的,如果你真想要在手机上面体验linux的快感,还是安装一些专业的程序,如:Termux、aidlux、LinuxDeploy、Andronix等等。我还是比较推荐Termux占用空间小,扩展性也不错,可玩性高。