Mobile Development 11 min read

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.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Performance Automation Practices for Xianyu Android Client

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" >>$file

CPU 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Flutterci/cdMetricsPerformance Testing
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.