關於安卓遊戲自動化方面的資料整理-1

凌漾發表於2024-06-13

關於安卓遊戲自動化方面的資料整理-1

最近裸辭,下週就可以撤了。今天沒什麼事情做,就心思整理下這方面的研究。
因為都是自己找資料,沒實踐出來可能就直接下結論了。要是有錯誤也希望能夠指正。
同時也不是專門的自動化方向的測試,更多是喜歡玩遊戲,會去寫一些指令碼。所以這篇文章可能主要是入門的一些內容。程式碼也都是基於 python 的。

好了,buffer 疊完了,開始正文了。


一、手:點選操作/按鈕操作

對於安卓自動化方向來說,問題之一就是如何對手機進行操作。遊戲方面更不用說,不同於原生應用,遊戲內的操作會更復雜。關於操作方面實現的方式如下:

1、備註

1、記得電腦連線手機,開啟手機的開發這選項

2、開發者選項中,開啟指標位置,可協助開發

3、小米手機需要開啟 USB 除錯(安全設定),允許模擬點選。

2、adb

從事安卓方向測試,肯定對 adb 都不陌生。這也是平常工作中最常用的工具之一了。在操作方面比較常用的:


adb shell input tap 500 500  # 點選手機(500,500)座標位置
adb shell input input keyevent KEYCODE_BACK  # 按手機的返回鍵

3、adbutils

在自身寫指令碼的時候,adb 肯定是要配合程式碼使用。python 中透過 adbutils 來呼叫 adb。記得先 pip install adbutils

下面的程式碼就是一個簡單的 demo,控制手機點選 500,500


from adbutils import AdbClient
adbc = AdbClient()   
adblist = adbc.device_list()
adb = adblist[0]  # 拿到所有連線手機adb中的第一個
adb.shell("input tap 500 500")

以下程式碼是一些常用的指令


adb.shell("dumpsys window |grep mCurrentFocus") # 獲取手機當前的視窗名稱
#執行結果 com.dragonplus.happyhospital/com.unity3d.player.UnityPlayerActivity
adb.shell("am start -n 包名/AppActivity") # 啟動應用(上一步的結果可作為包名和AppActivity)
adb.shell("am force-stop 包名") # 結束應用
adb.shell("pm clear 包名") # 清除應用資料,相當於重灌

透過 adbutils 我們就已經能夠做到一些簡單的自動化了。例如我之前有一個工作任務就是手機不同壓縮下,各貼圖的幀數變化。25 張圖片需要每張圖片展示 2 分鐘,並且還需要,用 3 臺裝置,分別測試 10 次,提高可信度。
最終就是用這種方式,下班掛機了兩個晚上解決的。但也有一些其他問題需要最佳化。

1、三個手機解析度不一致,辛虧只需要點一個按鈕,三臺手機就收集了各自按鈕的位置解決了。

2、過程中,若有一次點選失效,整個資料都會偏移。辛虧最後沒有發生這個問題。之前預想是,只要發生資料偏移,直接放棄本次整體資料。

4、uiautomator2

uiautomator2 根據調查應該是比較流程的安卓自動化工具了。pip install uiautomator2 進行安裝,手機首次執行時,會在手機上安裝兩個應用。


下面的程式碼就是一個簡單的 demo,控制手機點選 500,500


import uiautomator2 as u2

d = u2.connect_usb("pjhms4rsrgnjxckn") # adb devices獲得
d.click(500, 500) 

uiautomator2 的優勢在於,不僅透過座標進行點選,還可以透過標籤進行點選。
例如點選頁面上的模組按鈕


1、pip install weditor
2、python -m weditor
3、點選connect
4、dump Hierarchy 獲取重新整理頁面
5、複製對應的標籤

最終程式碼如下


import uiautomator2 as u2
import time
d = u2.connect_usb("pjhms4rsrgnjxckn")

time.sleep(3)
d(resourceId="com.topjohnwu.magisk:id/modulesFragment").click()

u2 在我看來是好用的,尤其是在原始 app 上進行測試。但也發現了一些問題,不得不衡量使用的效果。

1、不同手機匯出的標籤不一致

2、遊戲無法匯出標籤

3、minicap,minitouch 在安卓高版本存在問題,無法控制。之前找了一個 github 的專案,儲存了一些特殊機型及裝置的對應檔案。

https://github.com/varundtsfi/Android12Support_withso/tree/main/aosp
https://github.com/pl0514/Xiaomi_Vector_issue

4、u2 首次連線不同的手機需要下載檔案,但常常出現下載異常的問題。之前就是每次換電腦都把之前下載好的檔案也複製到另一臺電腦上

5、appium

說實話,對這個瞭解的不多。原因也是遊戲內獲取不到標籤。

6、airtest

在安卓遊戲自動化上,airtest 絕對是主角了。因為去網上查詢資料,最後都是指向它的。
我認為他的優勢在於以下幾點:

1、支援標籤,以及 poco 接入也能獲取遊戲的標籤了

2、封裝了影像識別。可透過影像進行點選

3、有 ide,支援錄製操作等,降低入手難度。

還是關於點選的程式碼


from airtest.core.api import *
connect_device("Android:///")
touch((500,500))

雖說知道這個 poco 事情,但一直沒有嘗試過。之後有時間的話,會專門試一下 unity3d 的專案接入 poco。

7、minitouch

這個上面也提到過,論壇裡面也有關於這個的帖子。單獨提到這個就是因為很多自動化操作框架都是基於這個實現的。鑽研的人感覺可以深入瞭解下。我是菜鳥一個,就放棄了

8、scrcpy

這個可能部分人使用過,一個安卓的投屏軟體,還有基於其二次開發的 QTscrcpy。主要的功能就是將手機畫面投屏到電腦上。既然能透過電腦操作手機,那麼肯定也是有辦法提前出他的操作功能的。

https://github.com/leng-yue/py-scrcpy-client

感謝大佬的這個專案,剛剛開啟專案,我發現專案竟然更新了!!!感謝大佬!感謝大佬!

在 scrcpy 中的 control 中,封裝了各自操作指令。用時還是先安裝 pip install scrcpy-client

import scrcpy

client = scrcpy.Client(
        device="pjhms4rsrgnjxckn",
        flip=False,
        bitrate=2000000,
        max_width=2340, # 注意,這裡需要是手機的最長畫素
        max_fps=10,
    )

client.start(threaded=True)
client.control.touch(500,500)


程式碼中會根據實際畫面的畫素進行換算,例如剛才的手機,我把 max_width 寫成 1080。那就縮小了 2340/1080 約等於 2.16。那樣填寫(100,100)最後就會去點選(216,216)

若想解決這個問題,就需要對 jar 檔案進行重新改寫。
https://github.com/Genymobile/scrcpy/tree/master

以前的版本我改過一次,目前電腦 AS 沒再打算花時間配置。簡單看了下程式碼,應該是把這裡修改。直接就是傳入什麼座標,返回什麼座標,無需計算。

剛剛搭了環境,簡單測試了一遍改成這樣就行了

int convertedX = contentRect.left + point.getX();
int convertedY = contentRect.top + point.getY();

build-makeproject-生成一個 server-debug.apk。再次改名成 scrcpy-server.jar 就行。

注意:python 安裝的 scrcpy-client 目前沒有更新到最新版。所有要使用最新版本的化,還得去 git 上 clone 程式碼。

9、autojst

這個也是簡單提一下,主要是用做手機端進行自動化的。直接在手機端操作生成自動化指令。


關於操作部分就寫這麼多了。上述也是我收集的一部分內容。希望有好用的工具還有朋友繼續分享。之後還會總結關於獲取影像,和識別相關的一些內容。

相關文章