从零开始:Android环境搭建与WebView套壳应用

文章目录

前言

我是一个写了 12 年后端(PHP/Go)的程序员,最近想给自己开发一个纯本地用的记账 APP。因为对 Android 开发一无所知,决定用最简单的方式:写一个 Android 壳,里面套一个 Vue 前端,前端负责所有业务逻辑和数据存储。这样我只需熟悉前端代码,就能快速产出可运行的 APK。

但没想到,从安装 Android Studio 到打包出第一个能联网的 APK,我踩了好多的坑:Gradle 下载超时、XML 编辑器找不到、WebView 死活发不出请求、跨域问题、缓存问题......折腾了整整一天。

为了记录本次踩坑经历,我把整个过程整理成这篇博文。只要按步骤操作,你也能在 1 小时内得到一个能运行、能联网的 Android 应用壳。

本文适合后端程序员、前端开发者或任何完全没接触过 Android 开发的小白。我会手把手带你从安装环境到生成 APK,再到在手机上跑起一个能联网的 WebView 应用。全文记录了所有我踩过的坑和解决方案,让你少走弯路。

特别声明:感谢DeepSeek对本文的大力支持,有了AI,写文章确实省力很多!但是AI有时候写着写着就开始乱写了,所以,AI输出的内容不要直接拿来用,一定要反复核查和修改。

还有,我发现AI真的就是不断犯错、不断道歉、再犯错、再道歉,然后自我进化的过程。我们每一个人都是AI的驯化师[捂脸]。

环境准备

下载 Android Studio

官网:https://developer.android.com/studio

我最初尝试了网上推荐的稳定版 Hedgehog | 2023.1.1 ,但遇到各种奇怪问题(网络超时、依赖下载失败)。最后换回最新版 Panda 2 | 2025.3.2 反而一切顺利。所以本文以最新版为例,但如果你遇到网络问题,可以尝试稳定版,核心步骤大同小异。

  • 文件名:android-studio-panda2-mac_arm.dmg(macOS M系列芯片)或对应 Windows 版本。
  • 下载后拖入 Applications 文件夹安装。

首次启动

打开 Android Studio,它会提示下载 SDK 组件。

  • 如果你不需要模拟器(只连真机调试),可以取消勾选 Android Emulator,只下载核心 SDK(约 500 MB 左右)。
  • 这一步需要联网,如果下载缓慢,可以自行解决网络问题(比如配置代理或使用镜像)。

吐槽:第一次启动竟然还要额外下载 1.7GB 的组件,为什么不能直接集成到 dmg 里?后来我查了下,如果 dmg 包含完整 SDK,体积会超过 10 GB,而且 SDK 版本更新频繁(几乎每月都有新版本),如果每次更新都重新下载整个 dmg,反而更麻烦。所以 Google 选择 dmg 只有 IDE 核心(~1GB),SDK 按需下载。虽然理解,但首次等待确实让人抓狂。

新建项目

  • 点击 New Project
  • 模板选择:Empty Views Activity(注意不是 Empty Activity,后者是 Jetpack Compose 模板)
  • 填写项目信息:
    • Name:MyVueApp(随便取)
    • Package name:com.example.myvueapp
    • Save location:自行选择(我用的是 /Users/xxx/AndroidStudioProjects/MyVueApp
    • Language:Java(必须选,Kotlin 也可以但本文以 Java 为例)
    • Minimum SDKAPI 21 (Android 5.0)(兼容 99% 设备)
    • Build configuration languageGroovy DSL (build.gradle)(Kotlin DSL 可能遇到配置问题)

点击 Finish,等待 Gradle 构建完成(第一次构建会下载依赖,可能较慢,耐心等待)。

项目结构

复制代码
MyVueApp/
└── app/
    └── src/
        └── main/
            ├── java/com/example/myvueapp/
            │   └── MainActivity.java          // 主界面逻辑
            ├── res/
            │   └── layout/
            │       └── activity_main.xml      // 界面布局
            └── AndroidManifest.xml            // 应用配置

我们后续会手动创建 assets 文件夹来存放前端代码。

编写 WebView 壳

修改布局文件

打开 app/src/main/res/layout/activity_main.xml,将内容替换为:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

坑点 :新版 Android Studio 默认打开 XML 是预览模式,需要切换到代码视图。在编辑器右上角有三个图标:Code / Split / Design ,点击 Code 即可编辑源码。如果找不到,可以右键文件选择 Open With → Editor。我找了半天才发现在右上角,差点以为文件打不开。

修改 MainActivity.java

打开 app/src/main/java/com/example/myvueapp/MainActivity.java,替换为:

java 复制代码
package com.example.myvueapp;

import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private WebView webView;

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

        webView = findViewById(R.id.webview);
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);               // 启用 JS
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);  // 禁用缓存
        webSettings.setDomStorageEnabled(true);               // 启用 localStorage
        webSettings.setAllowUniversalAccessFromFileURLs(true); // 允许跨域(重要)
        webSettings.setAllowFileAccessFromFileURLs(true);

        // 启用远程调试(方便 Chrome inspect)
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true);
        }

        webView.setWebViewClient(new WebViewClient());
        // 加载 assets 目录下的前端页面
        webView.loadUrl("file:///android_asset/index.html");
    }
}

关键点

  • setAllowUniversalAccessFromFileURLs(true) 解决 WebView 跨域问题。
  • setCacheMode(WebSettings.LOAD_NO_CACHE) 确保每次加载最新代码,避免缓存问题。

创建 assets 文件夹并放置前端文件

  • app/src/main 目录下,右键 → New → Directory ,输入 assets,回车。
  • assets 文件夹下,右键 → New → File ,输入 index.html,回车。

编写一个简单的前端测试页面

将以下代码粘贴到 index.html 中:

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试列表</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <style>
        body { font-family: system-ui; padding: 20px; margin: 0; background: #f5f5f5; }
        .header { font-size: 24px; font-weight: bold; margin-bottom: 20px; color: #333; }
        .list { background: white; border-radius: 12px; margin-bottom: 20px; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        .item { padding: 16px; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; }
        .item:last-child { border-bottom: none; }
        button { background: #007aff; color: white; border: none; padding: 14px; width: 100%; border-radius: 10px; font-size: 16px; font-weight: 500; cursor: pointer; }
        button:active { opacity: 0.7; }
    </style>
</head>
<body>
    <div id="app">
        <div class="header">📝 测试列表</div>
        <div class="list">
            <div v-for="item in items" class="item">
                <span>{{ item.name }}</span>
                <span>{{ item.time }}</span>
            </div>
        </div>
        <button @click="addItem">+ 添加记录</button>
    </div>
    <script>
        const { createApp, ref } = Vue;
        createApp({
            setup() {
                const items = ref([
                    { name: '示例条目 1', time: '刚刚' },
                    { name: '示例条目 2', time: '昨天' }
                ]);
                const addItem = () => {
                    items.value.push({ 
                        name: `新条目 ${items.value.length + 1}`, 
                        time: new Date().toLocaleTimeString() 
                    });
                };
                return { items, addItem };
            }
        }).mount('#app');
    </script>
</body>
</html>

注意 :这里使用了 Vue 的 CDN(https://unpkg.com/vue@3/dist/vue.global.js)。如果手机联网,页面会正常渲染。但如果手机没网或网络不稳定,页面会显示 {``{ item.name }} 这种模板语法。为了稳定,我们可以把 Vue 库下载到本地。

如何本地化 Vue

  1. 在电脑浏览器打开 https://unpkg.com/vue@3/dist/vue.global.js
  2. Command+S 保存为 vue.global.js
  3. vue.global.js 拖入 assets/js 文件夹
  4. 修改 index.html 中的引用:<script src="js/vue.global.js"></script>

这样应用完全不依赖网络,且加载更稳定。

打包 APK 并运行调试

生成签名密钥

  • 菜单 Build → Generate Signed Bundle / APK
  • 选择 APK → Next
  • 点击 Create new... 新建密钥库:
    • Key store path :选择一个存放路径(例如/Users/renxing/Documents/MyAppTest/mykey.jks),文件名 mykey.jks
    • Password123456
    • Confirm123456
    • Key Aliaskey0
    • Key Password123456
    • Confirm123456
    • Validity (years)25
    • Certificate :随便填,例如:
      • First and Last Name: test
      • Organizational Unit: test
      • Organization: test
      • City or Locality: test
      • State or Province: test
      • Country Code (XX): CN
  • 点击 OK,回到签名配置界面,Next
  • Build VariantsreleaseSignature Versions 勾选 V1V2
  • 点击 Finish,等待打包完成。

这里有个小插曲:Panda 版本菜单布局有点不同,Make Project 其实对应 Assemble Project。刚开始我找"Make Project"找了半天,后来才发现菜单叫法变了。而且,以上的数据在 Panda 版本中也省略了很多,如果发现你的界面和合理提到的字段不一致,直接跳过就行,不影响。

打包成功后,APK 位于 app/release/app-release.apk

安装到手机

  • 将 APK 通过微信、QQ 或数据线传到手机。
  • 在手机上点击 APK,系统会提示"禁止安装未知应用",点击"设置"并允许当前文件管理器(或微信)安装。
  • 安装完成后,桌面上会出现应用图标(名称是你在创建项目时填的 MyVueApp)。

打开应用,你应该能看到一个简单的 Vue 列表,点击"添加记录"按钮列表会变长。

最终效果预览:

开启网络访问能力

如果你的应用需要访问网络(比如调用后端接口),WebView 默认可能会遇到网络请求失败、跨域等问题。下面我们解决这些问题。

允许网络权限和明文流量

./app/src/main/AndroidManifest.xmlAndroidManifest.xml 中添加以下权限和配置:

xml 复制代码
<uses-permission android:name="android.permission.INTERNET" />

<application
    android:networkSecurityConfig="@xml/network_security_config"
    android:allowBackup="true"
    ... >

完整的 AndroidManifest.xml 应该像这样:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myvueapp">

    <!-- 添加网络权限 -->
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:networkSecurityConfig="@xml/network_security_config"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.MyVueApp">
        <activity android:name=".MainActivity" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

处理跨域和缓存

MainActivity.javaWebSettings 设置中,添加这几行:

java 复制代码
webView = findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);               // 启用 JavaScript
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);  // 禁用缓存,确保每次加载最新内容
webSettings.setDomStorageEnabled(true);               // 启用 localStorage
webSettings.setAllowUniversalAccessFromFileURLs(true); // 允许跨域访问
webSettings.setAllowFileAccessFromFileURLs(true);     // 允许文件协议访问
webView.setWebViewClient(new WebViewClient());

运行和调试

想查看 WebView 里的 console 输出和网络请求,可以用 Chrome 的远程调试工具(Chrome inspect),配合 Android Studio 的 Run 功能即可。

操作步骤

在 Android Studio 中点击 Run(绿色三角形按钮),应用会自动模拟启动。

打开 Chrome 浏览器,地址栏输入 chrome://inspect

  1. 在页面中找到你的应用(显示为 file:///android_asset/index.html 或你的应用包名)
  2. 点击下方的 inspect 链接
  3. 会弹出一个 DevTools 窗口,可以像调试网页一样查看:
标签 作用
Console 查看 console.log 输出、Vue 警告、JS 错误
Network 查看所有网络请求(请求头、响应体、状态码)
Application 查看 localStorage 中存储的数据
Elements 查看和调试 DOM 结构、CSS 样式

常见使用场景

  • 调试接口请求:点击"测试网络"按钮后,切换到 Network 标签,能看到请求是否发出、返回了什么数据
  • 检查数据存储 :在 Application → Local Storage → file:// 下,能看到本次存储的数据
  • 排查 Vue 报错 :Console 标签里会显示 [Vue warn] 之类的提示,帮助定位问题

这个调试方式非常方便。每次修改代码后,在 Android Studio 点击 Run,应用程序会自动更新,然后刷新 Chrome inspect 页面,就能看到最新的日志输出。我最初遇到 localStorage 不生效的问题,就是在 Application 标签里发现数据根本没写进去,才定位到忘记开 setDomStorageEnabled

踩坑经历

之前通过chrome浏览器调试的好好的,但是第二天,我像往常一样在 Android Studio 点击 Run,然后打开 chrome://inspect 准备调试,结果页面一直显示 "Device information is stale" ,即使完全退出 Chrome 重开也没用。更诡异的是,点击 inspect 后弹出的 DevTools 窗口是空白的,控制台报错 HTTP/1.1 404 Not Found

问了DeepSeek,给了很多解决方案都不行,后来又问了豆包,告诉我可以下载 Chrome Canary (金丝雀版),它是 Chrome 的开发版,版本号通常比稳定版高,能更好地匹配最新 WebView。安装后用 Canary 打开 chrome://inspect,设备信息立即正常显示,inspect 也能顺利打开 DevTools。

如果你也遇到类似的 404 或 stale 问题,不妨试试 Chrome Canary 或者换用 Edge 浏览器的(edge://inspect)。

服务端示例

为了验证网络请求是否成功,我在服务端写了一个简单的测试接口(ThinkPHP):

php 复制代码
public function test(Request $request)
{
    // 允许跨域
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
    header("Access-Control-Allow-Headers: Content-Type");

    $params = $request->post();
    // 记录日志
    \Log::write('收到参数:' . json_encode($params), 'info');

    return json([
        'code' => 200,
        'msg'  => 'success',
        'data' => $params
    ]);
}

在手机应用中点击"测试网络"按钮,发送 POST 请求,服务端成功收到数据并返回,证明 Android WebView 已具备完整的网络通信能力。

使用 WebStorm 开发前端

在 Android Studio 中编辑 HTML/JS 体验很差(没有语法高亮、代码补全、方法跳转)。这时我们可以用 WebStorm(或 PhpStorm)单独打开 assets 目录:

  • 打开 WebStorm,选择 File → Open ,定位到 /Users/xxx/AndroidStudioProjects/MyVueApp/app/src/main/assets
  • 之后就可以愉快地编写 Vue 代码了,享受 IDE 的智能提示。
  • 修改保存后,只需在 Android Studio 中点击 Run 或重新打开手机应用,即可看到最新效果。

我才发现 Android Studio 这个软件也是 JetBrains 全家桶的,我之前一直用的 GoLand 和 PhpStorm,我就说咋这么眼熟,哈哈!这下前端和后端开发工具都统一了。

完整项目代码

需要忽略的文件

将整个项目推送到 Gitee,但需要排除自动生成的文件。由于项目涉及多个开发工具(Android Studio 和 WebStorm),我们在不同目录分别设置了 .gitignore,确保不会提交 IDE 个人配置和构建产物。

  • 根目录 .gitignore

    ====== IDE 和系统文件 ======

    *.iml # Android Studio/IntelliJ 模块文件
    .gradle # Gradle 缓存目录
    /.idea # IntelliJ/Android Studio 项目配置(个人)
    .DS_Store # macOS 系统文件

    ====== 构建输出 ======

    /build # 根目录的构建输出
    /captures # Android Studio 截图/录屏文件
    .externalNativeBuild # NDK 构建输出
    .cxx # NDK 临时文件

    ====== 本地配置 ======

    local.properties # SDK 路径(每人不同)

  • app 模块的 .gitignore ,路径:/app/.gitignore

    ====== IDE 配置 ======

    .idea # WebStorm 打开 app 目录时产生的配置

    ====== 构建输出 ======

    /build # app 模块的编译产物
    /release # 签名的 APK 输出目录(包含 .apk 文件)

  • assets 目录的 .gitignore,路径:/app/src/main/assets/.gitignore

    ====== IDE 配置 ======

    .idea # WebStorm 单独打开 assets 目录时产生的配置

这样设计的好处是:无论你用哪个 IDE、打开哪个层级的目录,个人配置都不会被意外提交。

这些 .gitignore 文件已经在我的项目中配置好了,无需额外操作。克隆项目后,用 Android Studio 打开根目录即可正常构建;如果需要修改前端代码,用 WebStorm 打开 app/src/main/assets 目录即可。

项目视图切换

如果你在 Android Studio 里面找不到.gitignore文件,别慌。因为左侧项目树默认是 Android 视图,它只显示"开发相关"的文件,隐藏了:build/.gradle/.idea/ 等临时/配置文件,把 app/build.gradle 归到 Gradle Scripts 分组里了。这就是为什么你找不到 .gitignore

解决方法:切换到 Project 视图:

  1. 在左侧项目树的顶部 ,点击下拉菜单(默认显示 Android
  2. 选择 Project Files(或直接选 Project)
  3. 现在你就能看到和 Finder 一模一样的真实文件结构了

仓库地址

源代码:https://gitee.com/rxbook/android-demo-2026

至此,我们已经完成了 Android 开发环境的搭建,并成功创建了一个 WebView 壳应用,并可以打包安装到手机上。这个壳已经具备了最基本的联网能力(通过 WebView 设置)和前端交互能力。

下一篇我们将在这个壳的基础上,实现一个完整的"学生信息登记"应用,包括增删改查、搜索、分页、导出 JSON,敬请期待!

相关推荐
束尘2 小时前
Vue3 + Element Plus 实现 ZIP 压缩包在线预览(支持图片插入 / 文件预览)
前端·javascript·vue.js
hnlgzb2 小时前
安卓app中viewmodel的常用的用法有哪些?
android
伯远医学2 小时前
如何判断提取的RNA是否可用?
java·开发语言·前端·javascript·人工智能·eclipse·创业创新
恋猫de小郭2 小时前
Android Studio Panda 3 发布,CMP 导致的 Gemini 输入问题
android·ide·flutter·ios·android studio
全栈技术负责人2 小时前
Claw Code 系统架构与 Agent 运行机制解析
前端·系统架构·ai编程
zh_xuan2 小时前
Android compose 可见性动画未执行问题修复
android·compose
x-cmd2 小时前
[x-cmd] 专为 AI Agent 设计的无头浏览器,比 Chrome 速度快 9 倍且少用 16 倍内存 | Lightpanda
前端·chrome·ai·自动化·agent·浏览器·x-cmd
chxii3 小时前
Nginx 正则 location 指令匹配客户端请求的 URI
前端·nginx
qing222222223 小时前
Linux:/var/log/journal 路径下文件不断增加导致根目录磁盘爆满
linux·运维·前端