English version
ReDroid (Remote anDroid) 是自架「雲手機」的方案,透過docker在電腦上跑Android系統容器,再利用Scrcpy的鏡射螢幕功能連線到Android桌面。

ReDroid也是在電腦上用開源軟體跑Android APP的解決方案。因為別說雲手機了,很多Android手遊模擬器都是閉源軟體哪。相較之下,ReDroid除了ARM轉譯器以外都是開源的。更棒的是ReDroid支援GPU加速+ARM轉x86的轉譯器,這樣就可以玩大多數手機3D遊戲了。
對Linux用戶來說,這更是除了Waydroid和Android-x86以外,在Linux電腦高效率跑Android APP的方法。並且它比Waydroid更適合當作雲手機使用(參見自架雲手機)
本文將討論如何在x86架構的Linux電腦,用ReDroid玩ARM架構的手機遊戲。我們會在ReDroid映像檔加入ARM轉譯器+Google服務框架,以達成最佳使用體驗。
P.S. Windows和MacOS也可以用Docker跑ReDroid。
如果要用ReDroid玩手機遊戲,建議x86架構的電腦至少要有8GB以上RAM,因為有時ARM在轉譯成x86指令時會佔用大量RAM。
ReDroid在Github上有各大Linux發行版的安裝說明,Windows的WSL請參考我寫的這篇。
- 由於我是Arch Linux,要更換核心為
linux-zen
。在安裝linux-zen核心之後,更新GRUB選項。重開機,在GRUB選單的Advanced Options選取以linux-zen
核心開機。
1
2
3
4
5
6
7
8
9
10
| # 如果有Nvidia驅動,記得將其換成DKMS版本
sudo pacman -R nvidia
sudo pacman -S nvidia-dkms
# 確認沒有安裝binder_linux-dkms
yay -R binder_linux-dkms
# 安裝linux-zen核心
sudo pacman -S linux-zen linux-zen-headers
sudo mkinitcpio -p linux-zen
sudo grub-mkconfig -o /boot/grub/grub.cfg
|
接著安裝Docker,用於執行容器
安裝ADB和Scrcpy。Scrcpy現已包含傳輸音效的功能。
1
2
| sudo pacman -S android-tools
sudo pacman -S scrcpy
|
* 想要整合按鍵映射的圖形化Scrcpy界面,可以改裝QtScrcpy。
大部分電腦是x86架構,只能執行x86版的Android APP,然而很多手機遊戲只有ARM版,所以ReDroid需要ARM轉譯器。
Redroid作者發布的redroid:11.0.0-latest
和redroid:12.0.0-latest
映像檔已內建Google開發的ARM轉譯器libndk,我試過只有Android 11比較穩定,Gapps也可以用,所以下面以Android 11為例。
- 建立存放資料的目錄,新增docker-compose
1
2
3
| mkdir ~/redroid
cd redroid
vim docker-compse.yml
|
- 填入以下內容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| version: "3"
services:
redroid:
image: redroid/redroid:11.0.0-latest
stdin_open: true
tty: true
privileged: true
ports:
- "5555:5555"
volumes:
# 資料存放在目前目錄下
- ./redroid-11-data:/data
command:
# 啟用GPU硬體加速
- androidboot.redroid_gpu_mode=auto
# 設定libndk相關
- ro.product.cpu.abilist0=x86_64,arm64-v8a,x86,armeabi-v7a,armeabi
- ro.product.cpu.abilist64=x86_64,arm64-v8a
- ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi
- ro.dalvik.vm.isa.arm=x86
- ro.dalvik.vm.isa.arm64=x86_64
- ro.enable.native.bridge.exec=1
- ro.dalvik.vm.native.bridge=libndk_translation.so
- ro.ndk_translation.version=0.2.2
|
- 啟動服務
1
| sudo docker compose up -d
|
- 用ADB連線至本機的ReDroid:
1
2
3
4
5
| adb connect localhost:5555
# 如果連不上,用以下指令看一下容器內部發生什麼問題
sudo docker exec <容器ID> logcat
sudo docker logs <容器ID>
|
- 執行Scrcpy,連線到Android桌面:
1
| scrcpy -s localhost:5555 --audio-codec=raw
|
- 這樣就會看到Android的桌面了。

作者說Google服務框架是專有軟體無法內建,那麼就得自行安裝了。第一個方法是重新編譯映像檔,第二個是手動安裝OpenGApps。
不推薦第一個方法,耗時而且作者提供的GApps編譯教學又有其他APP偵測不到的問題。
這裡採用第二個方法:手動安裝,過程參考自:Install GApps Manually - Google Groups
到OpenGapps下載x86_64架構的Android 11 GApps,選擇最小化的pico版。
解壓縮,會看到以下目錄
1
2
3
4
5
| open_gapps-x86_64-11.0-pico-20220503
├── Core
├── GApps
├── META-INF
├── Optional
|
在解壓縮的目錄open_gapps-x86_64-11.0-pico-20220503
下面新增system
目錄。
接著,將Core
和GApps
目錄裡面的.lz
檔案都解壓縮,並將裡面的APK目錄按照對應的安裝目錄放到system
目錄。例如GApps/googletts-x86_64/nodpi/app/
下的GoogleTTS
目錄要放到/system/app
。
放好之後,system
下的目錄結構應該會長這樣:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| system
├── app
│ ├── GoogleCalendarSyncAdapter
│ │ └── GoogleCalendarSyncAdapter.apk
│ ├── GoogleContactsSyncAdapter
│ │ └── GoogleContactsSyncAdapter.apk
│ ├── GoogleExtShared
│ │ └── GoogleExtShared.apk
│ └── GoogleTTS
│ └── GoogleTTS.apk
├── etc
│ ├── default-permissions
│ │ ├── default-permissions.xml
│ │ └── opengapps-permissions-q.xml
│ ├── permissions
│ │ ├── com.google.android.dialer.support.xml
│ │ ├── com.google.android.maps.xml
│ │ ├── com.google.android.media.effects.xml
│ │ ├── privapp-permissions-google.xml
│ │ └── split-permissions-google.xml
│ ├── preferred-apps
│ │ └── google.xml
│ └── sysconfig
│ ├── dialer_experience.xml
│ ├── google_build.xml
│ ├── google_exclusives_enable.xml
│ ├── google-hiddenapi-package-whitelist.xml
│ └── google.xml
├── framework
│ ├── com.google.android.dialer.support.jar
│ ├── com.google.android.maps.jar
│ └── com.google.android.media.effects.jar
├── priv-app
│ ├── AndroidAutoPrebuiltStub
│ │ └── AndroidAutoPrebuiltStub.apk
│ ├── AndroidMigratePrebuilt
│ │ └── AndroidMigratePrebuilt.apk
│ ├── CarrierSetup
│ │ └── CarrierSetup.apk
│ ├── ConfigUpdater
│ │ └── ConfigUpdater.apk
│ ├── GoogleBackupTransport
│ │ └── GoogleBackupTransport.apk
│ ├── GoogleExtServices
│ │ └── GoogleExtServices.apk
│ ├── GoogleFeedback
│ │ └── GoogleFeedback.apk
│ ├── GoogleOneTimeInitializer
│ │ └── GoogleOneTimeInitializer.apk
│ ├── GooglePackageInstaller
│ │ └── GooglePackageInstaller.apk
│ ├── GooglePartnerSetup
│ │ └── GooglePartnerSetup.apk
│ ├── GoogleRestore
│ │ └── GoogleRestore.apk
│ ├── GoogleServicesFramework
│ │ └── GoogleServicesFramework.apk
│ ├── Phonesky
│ │ └── Phonesky.apk
│ ├── PrebuiltGmsCore
│ │ └── PrebuiltGmsCore.apk
│ └── SetupWizard
│ └── SetupWizard.apk
└── product
└── overlay
└── PlayStoreOverlay.apk
|
- 執行以下指令取得root權限:
1
2
3
4
| adb connect localhost:5555
adb -s localhost:5555 root
adb -s localhost:5555 remount
adb -s localhost:5555 shell "rm -rf system/priv-app/PackageInstaller"
|
- 接著將
system
目錄推送到ReDroid系統,並賦予權限:
1
2
3
4
5
6
| adb -s localhost:5555 push system /
adb -s localhost:5555 shell "pm grant com.google.android.gms android.permission.ACCESS_COARSE_LOCATION"
adb -s localhost:5555 shell "pm grant com.google.android.gms android.permission.ACCESS_FINE_LOCATION"
adb -s localhost:5555 shell "pm grant com.google.android.setupwizard android.permission.READ_PHONE_STATE"
adb -s localhost:5555 shell "pm grant com.google.android.setupwizard android.permission.READ_CONTACTS"
adb reboot
|
- 重新啟動ReDroid容器:
1
2
3
| cd ~/redroid
sudo docker compose down
sudo docker compose up -d
|
- 啟動Scrcpy
1
| scrcpy -s localhost:5555 --audio-codec=raw
|
開啟系統設定 → 應用程式,點選右上角顯示系統應用程式,將Google Play服務和Play商店的權限都開啟。
執行以下指令取得Android裝置ID,到Google網站註冊裝置,等個30分鐘後重新啟動Redroid容器,才能登入Google Play。
1
2
3
| adb -s localhost:5555 root
adb -s localhost:5555 shell 'sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \
"select * from main where name = \"android_id\";"'
|
目前即使有安裝libndk,Android 11的Play商店還是不給下載ARM架構的APP,請配合APKPure之類的應用程式商店安裝APP。
除了用容器內部的瀏覽器下載APK外,你還可以用ADB安裝APK至ReDroid容器。比方說到ApkMirror下載Line的APK,接著用ADB安裝:
1
| adb -s localhost:5555 install "jp.naver.line.android.apk"
|
你也可以用ADB的pull
和push
指令傳輸檔案。
關於螢幕解析度的調整,請參閱ReDroid和Scrcpy的使用說明。
如果要將ReDroid關機,將Scrcpy視窗關閉後,停止容器:
1
2
| cd ~/redroid
sudo docker compose down
|
之後可以再用此指令啟動ReDroid。ReDroid容器的/data
資料位於~/redroid/redroid-11-data
目錄,可以用來備份多個系統的檔案。
1
2
3
4
| cd ~/redroid
sudo docker compose up -d
adb connect localhost:5555
scrcpy -s localhost:5555
|
libndk是Google開發的專有軟體,含在Android Studio的模擬器裡面。根據ReDroid作者指示,我們可以手動從新版Android模擬器抽取libndk,再將其塞到ReDroid原生系統裡面。
這裡以Android 13為例,注意作者沒保證說一定能用。
安裝Android Studio,新增Android 13的虛擬機
透過ADB連線
1
2
3
| adb devices
adb shell
su
|
- 將libndk打包
1
| { find /system -name arm* -type d; find /system -name *ndk_translation*; find /system/etc -name *arm*; } | tar -cf /sdcard/nb.tar -T -
|
- 將libndk.so打包
1
| find system -type l | tar -cf /sdcard/so.tar -T -
|
- 退出ADB,將以上檔案傳回本機
1
2
3
4
| exit
exit
adb pull /sdcard/nb.tar .
adb pull /sdcard/so.tar .
|
- 將libndk.so加入到libndk的壓縮檔
1
2
| tar -xvf so.tar
find system -type l | tar -rf libndk_translation.tar -T -
|
- 新增
DOCKERFILE
,填入以下內容:
1
2
3
| FROM redroid/redroid:13.0.0-latest
ADD libndk_translation.tar /
|
- 開始建置含有libndk的Android 13映像檔,之後這個映像檔
redroid:13.0.0-libndk
就能拿去執行容器了。
1
| docker build . -t redroid:13.0.0-libndk
|