摘要
目的:提供一个稳定的下载场景,可以手动触发和定时触发下载,每次下载相同大小文件,研究下载场景的功耗影响
原理:把电脑当做服务器,手机测试App固定下载电脑存放的某个XXXMB的大文件,基于PowerMonitor进行电流监测和架构侧建立日志与埋点监控下载场景用来研究功耗影响
日志结果:方便以后我们量化某个固定大小的下载文件所需的时长、耗电量大小和平均电流大小,即为量化下载场景功耗提供稳定的测试环境
test.apk,download progress: 100%
Download completed. Total time: 41s964ms ms, File size: 315.23 MB, Download speed: 7876810.0 KB/s
实现方法:
1. 测试环境
手机和电脑连接相同的wif 热点
2. 电脑端配置
2.1 电脑端放置用于下载的测试文件
新建文件夹和下载文件 C:\Users\xxx\Desktop\test\test.apk
2.2 将电脑变成服务器,让手机通过 WiFi 从电脑下载文件
在C:\Users\xxx\Desktop\test目录下执行:python -m http.server 即可
2.2 cmd 窗口下使用:ipconfig,记录下ip地址
将Ip 地址填到:http://10.170.16.162:8000/test.apk
2.3 电脑浏览器http://10.170.16.xxx:8000/test.apk输入查看是否可以下载
如果可以下载,则表示电脑已经变成服务器了,接下来实现客户端App的代码就行
如果是浏览器下载的cmd窗口会如下打印
3. App的下载demo参考用例
3.1 下载代码
基于okhttp3的SDK
implementation("com.squareup.okhttp3:okhttp:4.9.0")
import android.content.Context
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.ResponseBody
import java.io.BufferedReader
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
fun downloadTestFile(context: Context) {
val url = "http://10.170.16.162:8000/test.apk"
val file = File(context.getExternalFilesDir(null), "test.apk")
downloadFile(url, file)
}
fun downloadFile(url: String, file: File) {
val client = OkHttpClient()
val request = Request.Builder().url(url).build()
val startTime = System.currentTimeMillis()
val response = client.newCall(request).execute()
if (!response.isSuccessful) throw IOException("Unexpected code $response")
val responseBody: ResponseBody? = response.body
val inputStream: InputStream? = responseBody?.byteStream()
val outputStream = FileOutputStream(file)
val buffer = ByteArray(4096)
var totalBytesRead: Long = 0
var bytesRead: Int
val fileSize: Long = responseBody?.contentLength() ?: 0
while (inputStream?.read(buffer).also { bytesRead = it ?: -1 } != -1) {
outputStream.write(buffer, 0, bytesRead)
totalBytesRead += bytesRead.toLong()
val progress = (totalBytesRead * 100 / fileSize).toInt()
println(file.name + ",download progress: $progress%")
}
inputStream?.close()
outputStream.close()
val endTime = System.currentTimeMillis()
val totalTime = endTime - startTime
val fileSizeInKB = fileSize
val downloadSpeed = fileSizeInKB / (totalTime / 1000f)
println("Download completed. Total time: ${TimeUtils.formatDuration(totalTime)} ms, " +
"File size: ${ByteUtils.formatBytes(fileSizeInKB)}, Download speed: $downloadSpeed KB/s")
}
3.2 App的下载日志
系统侧如果要监测下载行为,可以另行添加插桩和埋点进行监控,以下主要是app内自行打印
cmd窗口的触发打印
App logcat触发打印
从日志可以看出:方便以后我们量化某个固定大小的下载文件所需的时长、耗电量大小和平均电流大小,即为量化下载场景功耗提供稳定的测试环境