Performance Automation Practices for Xianyu Android Client
To meet Xianyu’s rapid‑release targets, the team built a CI‑integrated automation suite that gathers Flutter FPS, CPU, memory and network data via extended Android tools, drives mixed Flutter/Native UI tests with Appium and integration‑test, and generates lane‑by‑lane performance reports that quickly flag regressions across dozens of feature branches.
The Xianyu team, operating under a lean development model, faces strict performance goals (2‑week feature delivery, 1‑week development cycle, 1‑hour release readiness). Automation is critical for the success of their CI pipeline.
Problems identified:
Missing tools for Flutter performance data collection and UI automation; existing solutions are custom per business unit and do not support Flutter.
Test workload multiplies with the number of feature lanes (branches) in a release, making manual performance testing infeasible.
Solution overview:
Acquire Flutter performance metrics (FPS, CPU, memory, network) by extending native Android tools (e.g., dumpsys SurfaceFlinger) to handle Flutter's SurfaceView.
Implement UI automation for mixed Flutter/Native screens using Appium and Flutter's integration‑test framework.
Integrate performance scripts into CI so that each lane is automatically tested, results are collected, and alerts/reports are generated.
FPS collection script (Shell):
dumpsys SurfaceFlinger --latency -clear
#echo "dumpsys SurfaceFlinger..."
if [[ $isflutter = 0 ]]; then
window=`dumpsys window windows | grep mCurrent | $bb awk '{print $3}'|$bb tr -d '}'` # Get the current window
echo $window
fi
if [[ $isflutter = 1 ]]; then
window=`dumpsys SurfaceFlinger --list |grep '^SurfaceView'|$bb awk 'NR==1{print $0}'`
fi
if [ -z "$window" ]; then
window="SurfaceView"
fi
fi
$bb usleep $sleep_t
dumpsys SurfaceFlinger --latency "$window"|$bb awk -v time=$uptime -v target=$target -v kpi=$KPI "$awkfike" >>$fileCPU usage collection (Shell):
export bb="/data/local/tmp/busybox"
$bb top -b -n 1|$bb awk 'NR==4{print NF-1}'Memory statistics extraction (Shell):
do_statistics(){
((COUNT+=1))
isExist="$(echo $OUTPUT | grep "DalvikHeap")"
if [[ ! -n $isexist ]]; then
old_dumpsys=true
else
old_dumpsys=false
fi
if [[ $old_dumpsys = true ]]; then
java_heap="$(echo $OUTPUT | grep "Dalvik" | $bb awk '{print $6}' | $bb tr -d '\r')"
else
java_heap="$(echo $OUTPUT | grep "DalvikHeap" | $bb awk '{print $8}' | $bb tr -d '\r')"
fi
((JAVA_HEAP_TOTAL+=java_heap))
((JAVA_HEAP_AVG=JAVA_HEAP_TOTAL/COUNT))
if [[ $java_heap -gt $JAVA_HEAP_PEAK ]]; then
JAVA_HEAP_PEAK=$java_heap
fi
# Similar logic for native heap, graphics, unknown, etc.
}Network traffic extraction (Shell):
uid="$(dumpsys package packages|$bb grep -E "Package|userId"|$bb awk -v OFS=" " '{if($1=="Package"){P=substr($2,2,length($2)-2)}else{if(substr($1,1,6)=="userId")print P,substr($1,8,length($1)-7)}}'|grep $package|$bb awk '{print $2}')"
echo "Net:"$uid
initreceive=`$bb awk -v OFS=" " 'NR>1{if($2=="wlan0"){wr[$4]+=$6;wt[$4]+=$8}else{if($2=="rmnet0"){rr[$4]+=$6;rt[$4]+=$8}}}END{for(i in wr){print i,wr[i]/1000,wt[i]/1000,"wifi"};for(i in rr){print i,rr[i]/1000,rt[i]/1000,"data"}}' /proc/net/xt_qtaguid/stats | grep $uid|$bb awk '{print $2}'`
inittransmit=`$bb awk -v OFS=" " 'NR>1{if($2=="wlan0"){wr[$4]+=$6;wt[$4]+=$8}else{if($2=="rmnet0"){rr[$4]+=$6;rt[$4]+=$8}}}END{for(i in wr){print i,wr[i]/1000,wt[i]/1000,"wifi"};for(i in rr){print i,rr[i]/1000,rt[i]/1000,"data"}}' /proc/net/xt_qtaguid/stats | grep $uid|$bb awk '{print $3}'`
getnet(){
local data_t=`date +%Y/%m/%d" "%H:%M:%S`
netdetail=`$bb awk -v OFS=, -v initreceive=$initreceive -v inittransmit=$inittransmit -v datat="$data_t" 'NR>1{if($2=="wlan0"){wr[$4]+=$6;wt[$4]+=$8}else{if($2=="rmnet0"){rr[$4]+=$6;rt[$4]+=$8}}}END{for(i in wr){print datat,i,wr[i]/1000-initreceive,wt[i]/1000-inittransmit,"wifi"};for(i in rr){print datat,i,rr[i]/1000-initreceive,rt[i]/1000-inittransmit,"data"}}' /proc/net/xt_qtaguid/stats | grep $uid
echo $netdetail>>$filenet
}These scripts are invoked from the CI pipeline, generating performance reports (FPS, CPU, memory, network) for each feature lane. The reports include metrics such as frame‑diff, jank, MFS, OKT, and SS, allowing quick identification of regressions.
Results demonstrated that the automated system could monitor dozens of lanes per release, detect performance degradations early, and support further tooling (AI error detection, test case generation, etc.).
References: TesterHome topics 2232 & 4775, related articles on Flutter integration testing and large‑scale data processing.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
