共计 7784 个字符,预计需要花费 20 分钟才能阅读完成。
通过一段时间的优化,PerfDog4.0 全新来袭,先来看看都更新了神马
一,新版性能初探
- 【新增】新增图表常见操作提醒性能
- 【新增】新增高阶性能,子过程帧率精准测试
- 【优化】彻底解决局部 Android 手机无奈获取电量和内存等问题
- 【优化】解决 iOS 低版本无奈获取 FPS 等问题
- 【修复】修复一些已知问题
咱们发现新版减少了一些罕用 tip
优化了一些安卓以及 ios 局部机型或者零碎版本无奈获取局部数据的问题,如果还有一些获取不到数据或者连贯的问题,请查看
PerfDog 应用连贯相干阐明
二,子过程帧率精准测试阐明
这个子过程帧率获取对于目前来说应用多过程的利用来说十分有用哦,可能有些同学对于这个概念不是很清晰,咱们来一步步摸索;
这是啥?干啥用?怎么用?
多过程简介:
Android 平台,个别大型 APP,比方游戏有时候是多过程合作运行(微信小游戏,微视等 APP 及王者光荣等游戏多子过程),可抉择指标子过程进行针对性测试。默认是主过程。如图王者光荣
弄清出子过程帧率之前先须要搞清楚 Android 窗口是是啥。上面简要的概述下,具体还不了解的请度娘SurfaceFliger,或者查看这篇文章扒一扒安卓渲染原理
简略来说 surfaceflinger 是安卓零碎的一个服务,作用是承受多个起源的图形显示数据,将他们合成,而后发送到显示设施;
咱们来看看官网的形容
大类去看,个别 Android 主窗口 Activity 和与之对应的 View,有一种非凡的 View,如 SurfaceView, 他会独享一个 Surface,不与主窗口共享 Surface,独立渲染十分高效,反对 OpenglES 渲染。也就是说可能会呈现两类窗口 FPS。一个是 Activety 窗口帧率和 SurfaceView 窗口帧率。
在什么状况下会呈现两种类型窗口都有的状况呢?个别是游戏类型、直播类、视屏流、小游戏等类型利用会呈现有两种窗口。非凡状况下,可能会呈现多个 Activity 和多个 SurfaceView,对统计帧率造成很大艰难,须要肯定策略获取帧率。
游戏、直播、视频、小游戏等类型利用,PerfDog 默认获取的是 SurfaceView 的 FPS。其余传统应或 Web 用获取的是 Activity 帧率。
同时 PerfDog 高阶性能,反对用户本人抉择窗口类型帧率,特地针对小程序,小游戏等,能更精准测试指标窗口帧率,如下图 (微信小游戏 - 欢畅斗地主)
小游戏、直播、视频、游戏等类型利用,请抉择 SurfaceView
咱们来总结一下:
如果咱们子过程的 View 是 SurfaceView,那么子过程会独享一个 Surface,不与主窗口共享 Surface;
这里拿一个视频页举例,主线程和子线程实际上能够了解为叠加的状态,二者互不烦扰;也就是说咱们获取主线程的帧率是上面主过程的数据,而子过程帧率是两头的一小块轮播图的帧率数据,二者是独立的
三,用户自建 Web 云获取性能数据
在更新 4.0 后,咱们在 setting 界面能够发现能够自定义上传的云平台了
这里要怎么应用呢,如果咱们有本人的云平台,那咱们自定义一个链接申请就能够了;
上面我用 Tornado 框架做个简略的例子
首先定义路由:
(r"/", GetPerfDogData), (r"/icon", GetPerfDogIcon), (r"/screenshots", GetPerfDogScreenShots), (r"/done", GetPerfDogDone),
接下来解决办法
class GetPerfDogData(tornado.web.RequestHandler): """:fuc: 获取 PerfDog 性能数据""" def post(self): data = self.request.body.decode('utf8') data = parse.unquote(data) print("性能数据:",data) self.finish({ "errCode": 0, "errStr": "","reportId":""})
残缺代码:
#!/usr/bin/env python# -*- coding:utf-8 -*-import tornado.web, tornado.ioloopfrom urllib import parsedef Set_Ima(data): with open("img.jpg", "wb") as f: f.write(data["body"]) # 生成一张 img.jpg 的图片 class GetPerfDogData(tornado.web.RequestHandler): """:fuc: 获取 PerfDog 性能数据""" def post(self): data = self.request.body.decode('utf8') data = parse.unquote(data) print("性能数据:",data) self.finish({ "errCode": 0, "errStr": "","reportId":""})class GetPerfDogIcon(tornado.web.RequestHandler): """:fuc: 获取 PerfDog 利用图标""" def put(self): data = self.request.files['icon'] print("Icon 图标:", data) for imadata in data: Set_Ima(imadata) self.finish({ "errCode": 0, "errStr": "","reportId":""})class GetPerfDogScreenShots(tornado.web.RequestHandler): """:fuc: 获取 PerfDog 测试过程中生成的利用截图""" def post(self): passclass GetPerfDogDone(tornado.web.RequestHandler): """:fuc: 实现上传测试数据""" def put(self): passif __name__ == '__main__': CONTENTS_LIST = [] settings = { 'template_path': 'template', 'static_path': 'static',} application = tornado.web.Application([(r"/", GetPerfDogData), (r"/icon", GetPerfDogIcon), (r"/screenshots", GetPerfDogScreenShots), (r"/done", GetPerfDogDone), ], **settings) application.listen(8868) tornado.ioloop.IOLoop.instance().start()
运行脚本,把 ip 地址 + 端口号填进 server 里,如果有域名就填写域名,
点击上传数据,就能够看到数据信息啦
这里贴出一下目前的接口文档:
接口阐明 baseURL 须要配置,例如:http://abc.com/report 开始上传测试数据• path:• method: post• header:– Content-Type: 'multipart/form-data'• req– file_format: json/pb– data: file• resp {errCode: 0, errStr: "", reportId:""}上传测试过程中生成性能数据,如 fps、卡顿等等设置测试利用图标• path: /icon• method: put• header:– Content-Type: 'multipart/form-data'• req– reportId– icon: file• resp {errCode: 0, errStr: ""}上传测试过程中生成的利用截图• path: /screenshots• method: post• header:– Content-Type:'multipart/form-data'• req– reportId– file1: file– file2: file– file3: file– file4: file– file5: file– ...• resp {errCode: 0, errStr:""}一次能够上传多张 或者应用 zip 压缩多张图片上传实现上传测试数据• path: /done• method: put• header:– Content-Type: 'multipart/form-data'• req– reportId• resp {errCode: 0, errStr: ""}
留神这是 4.0 版本的接口文档哦。当前没准会变得哟!
再贴一份 flask 框架残缺的 demo 吧
report 文件
# coding: utf-8import osimport uuidfrom werkzeug.utils import secure_filenameclass Report(object): def __init__(self, base_dir): self.base_dir = base_dir def set_data_by_pb(self, file): filename = self.get_filename('data.pb') file.save(filename) def set_data_by_json(self, file): filename = self.get_filename('data.json') file.save(filename) def set_icon(self, file): filename = self.get_filename('icon.png') file.save(filename) def add_screenshots(self, files): for file in files: filename = self.get_filename(secure_filename(file.filename)) file.save(filename) def done(self): filename = self.get_filename('done') with open(filename, 'wb'): pass def get_filename(self, filename): return '%s%s%s' % (self.base_dir, os.sep, filename)class ReportManager(object): def __init__(self): self.base_dir = os.path.split(os.path.realpath(__file__))[0] + os.sep + 'data' if not os.path.exists(self.base_dir): os.mkdir(self.base_dir) def create_report(self): report_id = str(uuid.uuid4()) report_dir = self.get_report_dir(report_id) os.mkdir(report_dir) return report_id, Report(report_dir) def get_report(self, report_id): report_dir = self.get_report_dir(report_id) return Report(report_dir) def get_report_dir(self, report_id): return '%s%s%s' % (self.base_dir, os.sep, report_id)reportManager = ReportManager()def create_by_pb(file): (report_id, report) = reportManager.create_report() report.set_data_by_pb(file) return report_iddef create_by_json(file): (report_id, report) = reportManager.create_report() report.set_data_by_json(file) return report_iddef set_icon(report_id, value): report = reportManager.get_report(report_id) report.set_icon(value)def add_screenshots(report_id, screenshots): report = reportManager.get_report(report_id) report.add_screenshots(screenshots)def done(report_id): report = reportManager.get_report(report_id) report.done()
demo 文件
#! /usr/bin/python# coding: utf-8from flask import Flask, request, jsonifyimport reportapp = Flask(__name__)@app.route('/report', methods=['POST'])def create_report(): file_format = request.form['file_format'] if file_format == 'pb': report_id = report.create_by_pb(request.files['data']) elif file_format == 'json': report_id = report.create_by_json(request.files['data']) if report_id is None: res = {'errCode': -1, 'errStr': 'invalid arguments'} else: res = {'errCode': 0, 'errStr': 'success', 'reportId': report_id} return jsonify(res)@app.route('/report/icon', methods=['PUT'])def set_icon(): report_id = request.form['reportId'] report.set_icon(report_id, request.files['icon']) return jsonify({'errCode': 0, 'errStr': 'success'})@app.route('/report/screenshots', methods=['POST'])def add_screenshots(): report_id = request.form['reportId'] files = [] for name in request.files: files.append(request.files[name]) report.add_screenshots(report_id, files) return jsonify({'errCode': 0, 'errStr': 'success'})@app.route('/report/done', methods=['PUT'])def done(): report_id = request.form['reportId'] report.done(report_id) return jsonify({'errCode': 0, 'errStr': 'success'})
好啦,能够开始欢快的游玩啦!
延长浏览:
如何自定义数据文件服务器地址,构建本人 web 云
https://bbs.perfdog.qq.com/de…
点赞(0)