Android UI性能测试——使用 Systrace 查找问题
一 官方文档翻译
官文地址:https://developer.android.com/studio/command-line/systrace
systrace命令允许您在系统级别上收集和检查所有运行在设备上的进程的耗时信息。它结合了来自Android内核的数据,例如CPU调度程序,磁盘活动和app线程,最后生成HTML报告,类似于图1中所示。
图1:systrace HTML示例报告,程序默认抓取5秒内应用和系统的消耗。该报告突出显示了systrace认为的异常帧。
此报告提供了在给定时间段内Android设备的系统进程的总体情况。它还检查捕获的跟踪信息以突出显示它所发现的问题,例如在显示动作或动画时的UI jank,并提供有关如何修复它们的建议。但是, systrace工具不会收集有关app进程中代码执行的信息。有关app正在执行的方法以及它使用的CPU资源的更多详细信息,请使用Android Studio自带的的CPU profiler,您还可以生成跟踪日志并使用CPU profiler导入和检查它们。
本文档说明如何从命令行通过systrace生成报告,查看生成的跟踪文件,并使用它们分析和改进app用户界面(UI)的性能。
注意:在运行Android 9(API级别28)或更高版本的设备上,您还可以使用名为“系统跟踪”的系统应用程序来记录设备上的系统跟踪。
要运行systrace,请完成以下步骤:
1.从Android Studio下载并安装最新的Android SDK工具。
2.安装Python并配置环境变量。
3.使用USB调试将运行Android 4.3(API级别18)或更高版本的设备连接到开发系统。
Systrace是Android SDK中自带的一个命令工具,位于android-sdk/platform-tools/systrace/。
语法
要为app生成HTML报告,您需要使用systrace的以下语法从命令行运行:
$ python systrace.py [options] [categories]
例如,以下命令调用systrace记录设备活动并生成名为mynewtrace.html的HTML报告。对于大多数设备来说,此类别列表是合理的默认列表。
$ python systrace.py -o mynewtrace.html sched freq idle am wm gfx view \
binder_driver hal dalvik camera input res
提示:如果要在跟踪输出中查看任务的名称,则必须在命令参数中包含sched。
要查看已连接设备支持的类别列表,请运行以下命令:
$ python systrace.py --list-categories
如果未指定任何类别或选项,systrace默认会生成包含所有可用类别并使用默认设置的报告。可用的类别取决于您连接的设备。
全局选项
命令和命令选项
调查UI性能问题
systrace对于检测app的UI性能特别有用,因为它可以分析您的代码和帧率,以识别问题所在并提出可能的解决方案或建议。首先,按以下步骤操作:
1.在连接的设备上运行您的应用。
2.systrace使用以下命令运行(此命令会跟踪您的应用10秒钟)
$ python systrace.py -t [other-options] [categories]
3.在systrace运行的同时与您的应用互动。
4.在您定义的时间限制结束后(本次示例是10秒),systrace生成HTML报告。
5.使用Web浏览器打开HTML报告。
通过此报告,您可以检测设备CPU在记录期间的使用情况。
以下部分介绍了如何查阅报告中的信息以发现和修复UI性能问题。
查看帧和警告
如图2所示,该报告列出了每个进程沿时间轴的每个渲染帧。绿色帧表示在16.6毫秒内渲染并保持每秒60帧稳定帧率的帧,黄色或红色帧表渲染时间超过16.6毫秒的帧。
图2:Systrace报告显示放大耗时长的帧。
注意:在运行Android 5.0(API级别21)或更高版本的设备上,渲染帧的工作分配给了UI Thread和RenderThread。在以前的版本中,创建帧的所有工作都被UI Thread完成。
单击帧会突出显示它,并显示有关系统完成该帧所做工作的其他信息,包括警告。它还会向您显示系统在渲染该帧时执行的方法,因此您可以调查这些方法以获取UI jank的原因。
图3.单击异常帧,跟踪报告下方会出现一个警告,用于识别问题。
选择慢速帧后,您会在报告的底部窗格中看到警告。图3中显示的警告指出此帧的主要问题是在ListView回收和重新绑定中花费了太多时间 。点击跟踪中相关事件的链接,可以更详细地查看系统在此期间所执行的操作。
要查看Systrace工具在跟踪中发现的每个警告,以及设备触发每个警告的次数,请单击窗口最右侧的Alert按钮,如图4所示。警告面板可帮助您查看在跟踪中发生的问题,以及它们对jank的贡献频率。可以将警告面板视为要修复的错误列表。通常一个区域的微小变化或改进可以消除应用程序中的整个警告类别。
图4:单击右侧的Alert按钮显示警告面板。
如果你发现UI线程做了很多的工作,你需要找出具体是哪些方法消耗了大多数CPU时间。一种方法是将跟踪标记添加到您认为导致这些瓶颈的方法中,然后在systrace中查看这些函数调用。如果您不确定哪些方法可能导致UI线程出现瓶颈,请使用Android Studio的CPU Profiler。您可以使用CPU Profiler生成跟踪日志并导入和检查它们。
HTML报告的键盘快捷键
下表列出了查看systrace HTML报告时可用的键盘快捷键。
检查应用代码
因为systrace仅在系统级别显示有关进程的信息,所以在HTML报告中很难了解你的APP在给定时间内具体执行的方法。在Android 4.3(API级别18)及更高版本中,您可以使用代中的Trace类来标记HTML报告中的执行事件,您不需要通过检查代码来记录跟踪 。但是检查代码可以帮助您了解app代码的哪些部分可能会导致线程挂起或UI jank。这种方法与使用Debug类不同——Trace类只是向systrace报告添加标记,而Debug 类是通过生成.trace文件来帮助您详细检查app的CPU使用情况。
要生成包含已检测跟踪事件的systrace HTML报告,您需要使用systrace的-a或--app选项运行命令行并指定app的包名称。
下面的示例代码演示如何使用Trace类标记一个方法的执行,包括该方法中的两个嵌套代码块:
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
...
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Trace.beginSection("MyAdapter.onCreateViewHolder");
MyViewHolder myViewHolder;
try {
myViewHolder = MyViewHolder.newInstance(parent);
} finally {
// In 'try...catch' statements, always call <code><a href="/reference/android/os/Trace.html#endSection()">endSection()</a></code>
// in a 'finally' block to ensure it is invoked even when an exception
// is thrown.
Trace.endSection();
}
return myViewHolder;
}</p> <p>@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Trace.beginSection("MyAdapter.onBindViewHolder");
try {
try {
Trace.beginSection("MyAdapter.queryDatabase");
RowItem rowItem = queryDatabase(position);
mDataset.add(rowItem);
} finally {
Trace.endSection();
}
holder.bind(mDataset.get(position));
} finally {
Trace.endSection();
}
}
...
}
注意:当您多次调用beginSection(String)方法时,每次会调用离beginSection(String)方法最近的endSection()方法。因此,对于嵌套调用,例如上面示例中的调用,您需要确保将每个beginSection()方法的调用都正确匹配一个endSection()方法的调用。此外,在一个线程中你不能只调用beginSection()方法,您必须在同一线程中调用endSection()方法来结束它。
二 补充(摘自《大话APP测试2.0》)
Systrace是类似于Memory Monitor的一个缩小问题访问、初步判断问题的工具。但它也不是万能的,需要TraceView的配合才能最终定位问题。
实战:假设我们现在面对着一个比较卡的列表界面,应该按照如下的步骤来执行。
1)保证当前环境下测试的应用版本都是正确和稳定的。
2)在终端开启Systrace监听命令(一般开10s就足够了)。
3)在终端显示当前正在搜集Systrace时开始进行你认为卡顿的那些操作,比如滚动ListView、切换Tab等。
4)看到终端显示capture trace时意味着Systrace搜集trace已经结束,此时等待html报告生成即可。
打开Systrace报告,如果看到SurfaceFlinger这一项的色条间隔很大并且很不规则,这说明我们真实滚动列表时掉帧很厉害,从这个数据上面我们可以看出该ListView的功能体验很不好,并且能够计算出掉帧率。
知道掉帧率以及的确卡顿后,我们可以通过“W”、“A”、“S”、“D”把结果放大,然后查看在掉帧的时间段内应用到底做了什么,这样就能够大概定位问题出在什么地方了。
我们来总结一下,通过Systrace得到的信息有:
1)应用是否真的卡顿。
2)掉帧率是多少。
3)掉帧时应用到底在干什么。
4)单击Systrace报告中的警告或者错误的标签,看到对应的修改建议。
5)Kernel层CPU的使用情况。
……
Systrace也并不是所有的模块或功能都支持的,那么对于一些不支持但又要进行测试的功能应该怎么办?在Android4.3或者更高的版本中Android本身提供了Systrace类,可以进行相关的引用从而最终能够在报告中查看到。如下是官方文档中所提供的一段代码,大家可以参考。
public void ProcessPeople(){ Trace.beginSection("ProcessPeople");
try{
Trace.beginSection("Processing Jane");
try {
//code for Jane task...
}finish{
Trace.endSection();//ends "Processing Jane"
} Trace.beginSection("Processing John");
try {
//code for John task...
}finish{
Trace.endSection();//ends "Processing John"
}
}finish{
Trace.endSection();
//ends "ProcessPeople"
}
}
三 我的实战
C:\Users\Administrator>adb devices # 查看设备
List of devices attached
GSL7N16B10000581 device C:\Users\Administrator>D: # 进入D盘 D:\>cd software\Android\SDK\platform-tools\systrace # 进入Systrace目录 D:\software\Android\SDK\platform-tools\systrace>dir # 查看该目录:可看到有systrace.py文件
驱动器 D 中的卷是 软件
卷的序列号是 A80B-3BC5 D:\software\Android\SDK\platform-tools\systrace 的目录 2018\11\30 周五 14:25 <DIR> .
2018\11\30 周五 14:25 <DIR> ..
2018\11\22 周四 10:32 <DIR> catapult
2018\11\22 周四 10:32 11,738 NOTICE
2018\11\22 周四 10:32 1,456 systrace.py
2018\11\22 周四 10:32 41 UPSTREAM_REVISION
3 个文件 13,235 字节
3 个目录 28,734,406,656 可用字节 D:\software\Android\SDK\platform-tools\systrace>python systrace.py -l #查看设备支持的类别
gfx - Graphics
input - Input
view - View System
webview - WebView
wm - Window Manager
am - Activity Manager
sm - Sync Manager
audio - Audio
video - Video
camera - Camera
hal - Hardware Modules
app - Application
res - Resource Loading
dalvik - Dalvik VM
rs - RenderScript
bionic - Bionic C Library
power - Power Management
pm - Package Manager
ss - System Server
database - Database
network - Network
adb - ADB
sched - CPU Scheduling
freq - CPU Frequency
idle - CPU Idle
load - CPU Load
memreclaim - Kernel Memory Reclaim
binder_driver - Binder Kernel driver
binder_lock - Binder global lock trace NOTE: more categories may be available with adb root D:\software\Android\SDK\platform-tools\systrace>python systrace.py -o mynewtrace.html -t 10 sched freq idle am wm gfx view binder_driver hal dalvik camera input res #在honor 8 Android 8.0设备上运行,报如下错误 Exception in thread Thread-11:
Traceback (most recent call last):
File "D:\software\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "D:\software\Python27\lib\threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\tracing_agents\atrace_agent.py", line 196, in _collect_and_preprocess
trace_data = self._collect_trace_data()
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\tracing_agents\atrace_agent.py", line 256, in _collect_trace_data
result = self._stop_collect_trace()
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\tracing_agents\atrace_agent.py", line 243, in _stop_collect_trace
large_output=True, check_return=True, timeout=ADB_LARGE_OUTPUT_TIMEOUT)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\decorators.py", line 57, in timeout_retry_wrapper
retry_if_func=retry_if_func)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\utils\timeout_retry.py", line 157, in Run
error_log_func=error_log_func)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\utils\reraiser_thread.py", line 186, in JoinAll
self._JoinAll(watcher, timeout)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\utils\reraiser_thread.py", line 151, in _JoinAll
(len(alive_threads), len(self._threads)))
CommandTimeoutError: Timed out waiting for 1 of 1 threads. Outputting Systrace results...
Tracing complete, writing results
Traceback (most recent call last):
File "systrace.py", line 49, in <module>
sys.exit(run_systrace.main())
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\run_systrace.py", line 201, in main
main_impl(sys.argv)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\run_systrace.py", line 198, in main_impl
controller.OutputSystraceResults(write_json=options.write_json)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\systrace_runner.py", line 69, in OutputSystraceResults
self._out_filename)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\output_generator.py", line 99, in GenerateHTMLOutput
html_file.write(_ConvertToHtmlString(result.raw_data))
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\output_generator.py", line 121, in _ConvertToHtmlString
raise ValueError('Invalid trace result format for HTML output')
ValueError: Invalid trace result format for HTML output D:\software\Android\SDK\platform-tools\systrace>python systrace.py -o mynewtrace.html -t 10 sched freq idle am wm gfx view hal dalvik camera input res # 在huawei M2-803L android 5.0.1 EMUI 3.1设备上运行报如下错误
Starting tracing (10 seconds)
Tracing completed. Collecting output...
CRITICAL:root:(TimeoutThread-1-for-Thread-11) Exception on ReadFile(YVF6R1741500
0417, /sys/kernel/debug/tracing/tracing_on, retries=3, timeout=30), attempt 1 of
4: AdbCommandFailedError("(device: YVF6R17415000417) adb pull /sys/kernel/debug
/tracing/tracing_on 'c:\\users\\admini~1\\appdata\\local\\temp\\tmppdnptu\\tmp_R
eadFileWithPull': failed with exit status 1 and output:\n- adb: error: remote ob
ject '/sys/kernel/debug/tracing/tracing_on' does not exist\n",)
CRITICAL:root:(TimeoutThread-2-for-Thread-11) Exception on ReadFile(YVF6R1741500
0417, /sys/kernel/debug/tracing/tracing_on, retries=3, timeout=30), attempt 2 of
4: AdbCommandFailedError("(device: YVF6R17415000417) adb pull /sys/kernel/debug
/tracing/tracing_on 'c:\\users\\admini~1\\appdata\\local\\temp\\tmpepvljn\\tmp_R
eadFileWithPull': failed with exit status 1 and output:\n- adb: error: remote ob
ject '/sys/kernel/debug/tracing/tracing_on' does not exist\n",)
CRITICAL:root:(TimeoutThread-3-for-Thread-11) Exception on ReadFile(YVF6R1741500
0417, /sys/kernel/debug/tracing/tracing_on, retries=3, timeout=30), attempt 3 of
4: AdbCommandFailedError("(device: YVF6R17415000417) adb pull /sys/kernel/debug
/tracing/tracing_on 'c:\\users\\admini~1\\appdata\\local\\temp\\tmpiyef2y\\tmp_R
eadFileWithPull': failed with exit status 1 and output:\n- adb: error: remote ob
ject '/sys/kernel/debug/tracing/tracing_on' does not exist\n",)
Exception in thread Thread-11:
Traceback (most recent call last):
File "D:\software\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "D:\software\Python27\lib\threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\tracing_agents\atrace_agent.py", line 196, in _collect_and_preprocess
trace_data = self._collect_trace_data()
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\tracing_agents\atrace_agent.py", line 256, in _collect_trace_data
result = self._stop_collect_trace()
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\tracing_agents\atrace_agent.py", line 247, in _stop_collect_trace
if int(self._device_utils.ReadFile(is_trace_enabled_file)):
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\decorators.py", line 57, in timeout_retry_wrapper
retry_if_func=retry_if_func)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\utils\timeout_retry.py", line 157, in Run
error_log_func=error_log_func)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\utils\reraiser_thread.py", line 186, in JoinAll
self._JoinAll(watcher, timeout)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\utils\reraiser_thread.py", line 158, in _JoinAll
thread.ReraiseIfException()
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\utils\reraiser_thread.py", line 81, in run
self._ret = self._func(*self._args, **self._kwargs)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\utils\timeout_retry.py", line 150, in <lambda>
child_thread = reraiser_thread.ReraiserThread(lambda: func(*args, **kwargs), File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\decorators.py", line 47, in impl
return f(*args, **kwargs)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\device_utils.py", line 1781, in ReadFile
return self._ReadFileWithPull(device_path)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\device_utils.py", line 1733, in _ReadFileWithPull
self.adb.Pull(device_path, host_temp_path)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\sdk\adb_wrapper.py", line 474, in Pull
self._RunDeviceAdbCmd(cmd, timeout, retries)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\sdk\adb_wrapper.py", line 301, in _RunDeviceAdbCmd
check_error=check_error)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\decorators.py", line 51, in timeout_retry_wrapper
return impl()
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\decorators.py", line 47, in impl
return f(*args, **kwargs)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\..\..\devil\devil\android\sdk\adb_wrapper.py", line 281, in _RunAdbCmd
args, output, status, device_serial)
AdbCommandFailedError: (device: YVF6R17415000417) adb pull /sys/kernel/debug/tra
cing/tracing_on 'c:\users\admini~1\appdata\local\temp\tmp_ygea9\tmp_ReadFileWith
Pull': failed with exit status 1 and output:
- adb: error: remote object '/sys/kernel/debug/tracing/tracing_on' does not exis
t Outputting Systrace results...
Tracing complete, writing results
Traceback (most recent call last):
File "systrace.py", line 49, in <module>
sys.exit(run_systrace.main())
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\run_systrace.py", line 201, in main
main_impl(sys.argv)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\run_systrace.py", line 198, in main_impl
controller.OutputSystraceResults(write_json=options.write_json)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\systrace_runner.py", line 69, in OutputSystraceResults
self._out_filename)
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\output_generator.py", line 99, in GenerateHTMLOutput
html_file.write(_ConvertToHtmlString(result.raw_data))
File "D:\software\Android\SDK\platform-tools\systrace\catapult\systrace\systra
ce\output_generator.py", line 121, in _ConvertToHtmlString
raise ValueError('Invalid trace result format for HTML output')
ValueError: Invalid trace result format for HTML output
systrace-example-error
实战总结:
1.测试发现目前运行Systrace命令只能使用Python2.7而不能使用Python3.X。
2.第一次运行Systrace命令时报错:ImportError: No module named win32con。
解决方法:通过命令pip install pypiwin32或者python -m pip install pypiwin32 来安装pypiwin32。
如果你没有pip,请参考下面步骤:
下载(https://pypi.python.org/pypi/pip);
解压;
安装(Python setup.py install);
添加环境变量:D:\software\Python27\Scripts。
PS:我的电脑是装了2个Python,一个Python2.7,一个Python3.5,结果执行pip install pypiwin32命令时把模块安装到了Python3.5里,于是通过Python2.7执行Systrace命令时发现依然报错。所以请确认你的pypiwin32确实安装到了Python2.7里(最好的办法就是安装前先卸载Python3.5)
3.解决了上面报错后,发现又报错:ValueError: Invalid trace result format for HTML output。查看stackoverflow后也没找到合适的解决方案。
Android UI性能测试——使用 Systrace 查找问题的更多相关文章
- Android UI性能测试——使用 Gfxinfo 衡量性能
Android官方文档翻译 原文地址:https://developer.android.com/training/testing/performance参考:https://www.jianshu. ...
- Android 性能优化(25)*性能工具之「Systrace」Analyzing UI Performance with Systrace:用Systrace得到ui性能报告
Analyzing UI Performance with Systrace In this document Overview 简介 Generating a Trace 生成Systrace文件 ...
- Android UI性能优化详解
设计师,开发人员,需求研究和测试都会影响到一个app最后的UI展示,所有人都很乐于去建议app应该怎么去展示UI.UI也是app和用户打交道的部分,直接对用户形成品牌意识,需要仔细的设计.无论你的ap ...
- Android UI组件----ListView列表控件详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
- Android应用程序资源的查找过程分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8806798 我们知道,在Android系统中, ...
- Android app性能测试小结(7个性能指标)
1.性能测试的几个指标: 2.性能测试环境准备: 3.启动时间 3.1,监控值的获取方法 启动分为冷启动和热启动,冷启动:应用程序首次启动,进程首次创建并加载资源的过程:热启动:应用程序启 ...
- Appium 在 Android UI 测试中的应用
原文地址:https://blog.coding.net/blog/Appium-Android-UI Android 测试工具与 Appium 简介 Appium 是一个 C/S 架构的,支持 An ...
- iPhone/iPad/Android UI尺寸规范 UI尺寸规范,UI图标尺寸,UI界面尺寸,iPhone6尺寸,iPhone6 Plus尺寸,安卓尺寸,iOS尺寸
iPhone/iPad/Android UI尺寸规范 UI尺寸规范,UI图标尺寸,UI界面尺寸,iPhone6尺寸,iPhone6 Plus尺寸,安卓尺寸,iOS尺寸 iPhone界面尺寸 设备 分辨 ...
- Android ui 测试课堂笔记
开始接触Android ui测试了,笔记如下 模拟器 Genemotion , the fastest android simulator in the world Android ui 测试工具 S ...
随机推荐
- UnitTest测试框架-操作步骤
一.UnitTest 1. TestCase 说明:测试用例 1.新建类并集成unittest.TestCase 2. TestSuite 说明:测试套件(多条用例) 方法: 1. 实例化 suite ...
- Redis 中 byte格式 写入、取出
实体类: package com.nf.redisDemo1.entity; import java.io.Serializable; public class News implements Ser ...
- H5本地离线存储
前言上一篇文件结尾,有同学问我本地存储图片方法,其实本地存储方式有很多,我们打开谷歌浏览器,查看源代码,在resources页签中,有web SQl ,indexedDB等等,我前面文章讲过Local ...
- numpy的基础运算1
import numpy as np #int16和int32内存少,int64内存大但精度高 a = np.array([1,23,4],dtype=np.int32) b = np.zeros(( ...
- Android空包签名
空包签名 搜狗.优亿等Android市场,上传应用需要提供一个与要上传的应用相同签名的空包.这个空包是相应官方市场提供的,下载好之后需要使用命令行进行签名.具命令如下: 1 jarsigner -ve ...
- Laravel Study(使用 Laravel )
開始 伺服器及相關工具安裝自行建立,在伺服器跟目錄下 有兩種方式建立 Laravel 專案,這裡使用 composer 建立專案 使用 composer 要在 PHP 5.3.2 以上才能使用 com ...
- VI.应用-Trajectory Data Mining
$textbf{Trajectory Data Mining: An Overview}$ 很好的一篇概述,清晰明了地阐述了其框架,涉及内容又十分宽泛.值得细读. 未完成,需要补充. $textbf{ ...
- js案例之使用正则表达式进行验证数据正确性
#js案例之使用正则表达式进行验证数据正确性 代码上传至 "GitHub" 样例: <tr> <td>密码:</td> <td> & ...
- MySQL多表查询、事务、DCL:内含mysql如果忘记密码解决方案
MySQL多表查询.事务.DCL 多表查询 * 查询语法: select 列名列表 from 表名列表 where.... * 准备sql # 创建部门表 CREATE TABLE dept( id ...
- bootstrap简介与入门
bootstrap前端框架 1.概念:一个前端开发的框架,Bootstrap,来自 Twitter,是目前很受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JavaScript 的,它 ...