專案定位
WebToApp 是 GitHub 上由開發者 shiaho 維護的開源 Android 應用,授權為 Unlicense。它的定位不是在電腦上跑一套打包流程,而是把手機本身當成 APK 工作台:使用者輸入網址、HTML 專案或帶服務端的程式碼,App 就在裝置內產生一個已簽章、可直接安裝的 APK,也能輸出可上架 Google Play 的 AAB。repository 的說明明確把它和一般「把網址包進 WebView」的工具區隔開來,差異點在於它會真的在手機上以 fork+exec 方式啟動完整的伺服器執行環境、內建一組偏向反審查的網路堆疊,並在裝置上完成簽章與 Play 打包,全程不需要個人電腦或遠端建置伺服器。
依 repository 所述,它能處理十二種應用類型:Web、HTML、前端框架靜態輸出、WordPress、Node.js、PHP、Python、Go、圖片、影片、相簿,以及多站台 Multi-Web。其中服務端類型預設關閉,需在「關於 → 進階功能」開啟;相簿不需開關。這代表它不是單一功能的工具,而是一個把多條技術路線塞進同一個 App 的整合體。
核心做法
WebToApp 的打包方式,是以一個預先編譯好的 shell 模板 APK 為基底,在二進位 AXML 與 ARSC 層級修補:注入設定與資源、依使用者勾選裁剪權限、最後用 apksig 完成 V1、V2、V3 簽章。設定來源是單一的 WebApp 資料模型(data/model/WebApp.kt)及其對應的 Config 類別,這些設定會沿著完整的打包傳遞鏈進入產出的 APK。換句話說,編輯器裡看到的每一個開關,都必須在模板與設定鏈兩端同時支援,否則就會產生設定漂移;repository 因此放了 check_config_field_drift.py 這類 CI 檢查來擋住不一致。
在專案結構上,repository 含三個 Gradle 模組:app 是完整的建置宿主(編輯器介面、匯出流程、執行環境、預覽),shell 是被嵌進產出 APK 的執行期模板,clone-host 則是 App 複製與識別重塑用的宿主端程式庫。執行期程式碼在 app 內撰寫,再同步進 shell,讓共用行為只有一份來源;shell 會被編譯成 webview_shell.apk。另有一組 feature-stacks 以可移植套件(dex、stack.arsc、資源與 manifest 片段)形式存在,只有在匯出設定啟用該功能時才注入產出的 APK。這些設計顯示作者對「同一份程式碼服務多個輸出目標」的問題有明確處理,而不是把程式碼複製多份。
技術亮點
最值得注意的一點是它真的在 Android 上執行服務端執行環境。Node.js 18.20 跑在獨立的 :nodejs 行程中,透過原生 node_launcher 載入 libnode.so,並支援自訂原生 .node 擴充;PHP 8.4 來自 pmmp/PHP-Binaries,首次使用時下載,附 Composer 2.10 與自訂原生擴充;Python 3.14 可跑 Flask、Django、FastAPI(透過 uvicorn)等,pip 依賴解析到 .pypackages;Go 1.26 使用官方 Linux arm64 工具鏈,能在裝置上執行 go build、go mod 與 go run,並有原生 go_exec_loader 包裝層;WordPress 7.x 則跑在本機 PHP 加 SQLite 之上。由於這些打包後的二進位檔無法直接使用系統解析器,專案另外提供一個在 Android JVM 內運作的本地 DNS 橋接代理,讓執行環境能正常解析 DNS 與對外發送 HTTP。
這個能力有一個關鍵取捨:產出的 APK 刻意把 targetSdk 固定在 28,因為正是這個層級允許它從應用儲存空間 fork+exec 原生執行環境;宿主 App 自身則目標 36。副作用是宿主端在 SELinux 的 W^X 限制下無法預覽這類執行環境,會以明確訊息降級,但 Node.js 的 JNI 預覽與所有已匯出的 App 不受影響。README 也直言防毒引擎會把低 targetSdk 的建置標記為舊版惡意軟體,這是使用這條路線必須接受的現實。
網路層是另一個重點。它支援 DNS-over-HTTPS(七家供應商加自訂端點)、TLS 指紋偽裝(模擬 Chrome 131、Firefox 133、Safari 18 的 JA3 特徵,透過本地 TLS 中間人橋接讓送出的 ClientHello 像真實瀏覽器)、在 WebView 與 GeckoView 雙引擎上啟用 Encrypted Client Hello 以加密 SNI、靜態與 PAC 與 SOCKS5 代理,以及針對被 CORS 擋住的單頁應用的繞道。隱私面則包含五十多種指紋向量偽裝、以 hosts 規則為基礎的廣告封鎖(內建二十份社群過濾清單並以 MutationObserver 做外觀層過濾)、PBKDF2 加 AES-256-GCM 的資源加密,以及加密開啟時的執行期硬化(反除錯、反 Frida、DEX 竄改檢查)。
擴充與自動化
WebToApp 不只打包,還在產出的 App 內提供擴充機制。內建模組包含影片下載、深色模式、元素封鎖、頁內搜尋、媒體下載器、頁面選單、隱私保護、網址切換器、影片增強、網頁分析與內容增強等,這些模組以簡單的 plugin.json 描述觸發時機與權限。它也支援 Greasemonkey/Tampermonkey 風格的 .user.js 腳本與 GM_ 系列 API,以及 MV3 的 Chrome 擴充執行環境(含 chrome.* 的相容層),並能在 App 內即時搜尋 Chrome 線上應用程式商店安裝擴充,離線時退回手動匯入。社群模組市場以 repository 內的 registry.json 與 submissions.json 作為目錄,App 只顯示兩份檔案都存在的模組,CI 會用 validate_modules.py 驗證,並由 generate_submissions.py 依 git 紀錄與 GitHub API 確認模組是否經合併的 PR 進入主線。
另一個獨立賣點是內建 Agent:以自然語言驅動、透過工具呼叫迴圈操作整個 App,最多約六十個工具,涵蓋建立與編輯與建置與匯出應用、管理連接埠與瀏覽器引擎、安裝或清除執行環境、廣告封鎖規則、設定模板、使用統計、App 複製與批次匯入、Play 政策檢查與模組開發。只讀工具直接執行,寫入類工具會先跳權限對話框,另有「提出計畫、等待核准、再執行」的模式,並對 429 與 5xx 做自動重試。模型端可接 Chat Completions、Anthropic Messages、OpenAI Responses,或 Gemini 與本地 Ollama、LM Studio、VLLM。
適用情境
最直接的使用者是個人開發者與小型團隊,想把既有網站快速變成可安裝的 App:落地頁、內部工具、儀表板、文件站都屬於這一類。其次是內容打包情境,例如把相簿、課程素材或影音做成離線可瀏覽的 App,或把 WordPress 站點連同主題與外掛做成可攜帶的展示包。第三類是需要在小服務端上驗證想法的人,例如用 Node.js、PHP 或 Python 寫一支小 API,直接包成手機可安裝的 App 做展示或原型。第四類是網路環境受限、或不想把原始碼交給第三方雲端建置服務的使用者,因為整個流程都在自己的裝置上完成。repository 內的 sample_projects 放了 Go 的 Echo、Fiber、Gin 儀表板、Node.js Express 與 MkDocs、VitePress 範例,以及內建插件清單,這些是可立即試跑的示範,並非專案的主要價值所在。
導入限制與風險
第一個實務責任是簽章金鑰。金鑰在手機上產生與保存,一旦遺失就無法更新既有的 App,而這類金鑰通常也牽涉到 Play 上架與企業內部派送。第二個限制是散布管道:五種服務端執行環境類型與開啟資源加密的建置無法走 Play 的 AAB 路線,只能以 APK 散布,因為 Play 要求的目標 API 層級會破壞它們的 fork+exec 執行環境;其餘類型則可正常上架。這些服務端形態長期綁在 targetSdk 28,而 Play 的目標 API 要求會逐年提高,這條路線未來是否仍可行,取決於平台政策的後續變化,無法在此時斷言。
第三,執行環境與 GeckoView 的原生程式庫是首次使用時才下載,來源包括第三方(pmmp/PHP-Binaries、dl.google.com 等),離線或來源失效時功能即不可用,也意味著這些執行環境的供應鏈並不在這個 repository 的控管範圍內。第四,啟動碼驗證跑在客戶端;repository 的遠端啟動文件中自己也承認,開源宿主可被改包繞過,遠端驗證只是提高門檻並提供吊銷與輪替能力,並非防破解保證。第五,功能面極大,設定漂移、測試覆蓋與長期維護成本都高;repository 內保留了 UI 設計系統遷移的歷史債務允許清單,資料庫 schema 版本也已推進到四十多版,可以看出這是一個仍在快速演進與持續重構的專案。最後,App Modifier、裝置偽裝與 APK 複製等能力本身具有被濫用的可能,repository 只針對裝置偽裝要求取得使用者知情同意;此外,使用這個工具產出的 App 需要自己的隱私政策,builder 的隱私政策並不涵蓋。
成熟度判斷
這不是教學樣板或展示用 demo。它有三個 Gradle 模組、雙語 VitePress 文件站、具 PR 驗證流程的模組市場、F-Droid 變體建置、Robolectric 單元測試,版本已到 2.6.9(versionCode 71)。但成熟不等於低風險:它把大量高風險能力集中在單一 App 內,並以 Unlicense 這種幾乎不設限的授權釋出,採用者必須對簽章金鑰保管、散布管道選擇、執行環境來源信任與法律合規自行負責。較合理的態度是先從不涉及服務端執行環境與加密的 Web 或靜態前端類型開始試用,確認建置流程與簽章管理符合自身需求後,再評估是否導入更複雜的路線。