安卓如何查看隐藏类的源码,如PhoneWindow,ViewRootImpl等
1.ctrl+N打开页面
2.选择选项All,右侧Include勾选选中,然后再查找自己想查找的源码如PhoneWindow,ViewRootImpl就可以查到了
vim 操作命令
1、默认不可编辑
2、按 i 键 ,进入输入模式,可编辑文本内容
3、编辑完成,按 esc 键,退出输入模式
4、按 shift + : 键,按wq!键,按回车键,完成保存退出vim。
若不想保存文本,按 shift + : 键,按 q! 键,按回车键,直接退出vim。
android studio 显示local changes:
打开 Settings/Preferences/Version Control/Commit ,将 Use non-modal commit interface 选项 取消勾选 即可。
直接跳转到安卓应用商店:
清单资源检查
gradlew processDebugManifest --stacktrace
检查资源依赖
gradlew app:dependencies
把主线程处理每一条消息的日志打印出来
Looper.getMainLooper().setMessageLogging(msg -> Log.v("test-looper",msg));
消息队列的快照
Looper.getMainLooper().dump(new Printer() {
@Override
public void println(String x) {
Log.v("message",""+x);
}
}, "test");
使用 Debug API 记录 CPU 活动
您可以使用 Debug
API,让应用能够在 CPU 性能剖析器中开始和停止记录 CPU 活动。
当您的应用调用 startMethodTracing(String tracePath)
时,CPU 性能剖析器将开始记录;当您的应用调用 stopMethodTracing()
时,CPU 性能剖析器将停止记录。在记录使用此 API 触发的 CPU 活动时,CPU 性能剖析器会将 Debug API 显示为正在发挥作用的 CPU 记录配置。
如需使用 Debug
API 控制 CPU 活动的记录,请将检测的应用部署到搭载 Android 8.0(API 级别 26)或更高版本的设备上。
火焰图的生成
使用“Flame Chart”标签检查跟踪数据
https://developer.android.com/studio/profile/inspect-traces
onStop,onDestroy有可能不执行
内存紧张被回收导致,onPause可能10秒后才执行,因为没有同步信号,走的是idleHandler
View.post逻辑
public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); } // 上面部分代码,是从ViewRootImpl的Handler而来,是主线程执行 // 前提是执行过dispatchAttachedToWindow // Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().post(action); // 这里并不是立即执行,而是要等到dispatchAttachedToWindow才执行,执行也是 return true; } Class HandlerActionQueue public void executeActions(Handler handler) { synchronized (this) { final HandlerAction[] actions = mActions; for (int i = 0, count = mCount; i < count; i++) { final HandlerAction handlerAction = actions[i]; handler.postDelayed(handlerAction.action, handlerAction.delay); } mActions = null; mCount = 0; } }
在 onAttachedToWindow
能获取到 View 的宽高吗
不能,performTraversals()中 dispatchAttachedToWindow 在performMeasure之前
翻译插件 ECTranslation2
修改快捷键 shift+m
触摸事件的速度追踪/惯性滑动
参考ViewPager2的FakeDrag代码,使用的VelocityTracker,然后使用RecyclerView.Fling()
被标识被@hidden的代码不会被打包进去
如:SomeArgs
Accessibility
>=21,这套被应用在了核心源码里面,可以当做模拟事件触发,比如RecyclerView里就有
查找删除无用资源
方法1:
1、在Anaylze中选择Run Inspection by Name…
2、在点击之后弹出的窗口输入unused resources后,回车
3、根据情况,选择情况,选择整个项目、指定Module…,也可以自己过滤。点击ok
4、得到结果,里面全是没用的文件。可以一个个删,也可以一次性删除
方法2:
通过设置代码压缩来确定哪些无用,在debug/usage.txt和unsource.txt
改造过的monkey
阿里 Macaca的NoSmoke
双端:NoSmoke
字节的Fastbot
Android:GitHub - bytedance/Fastbot_Android: Fastbot(2.0) is a model-based testing tool for modeling GUI transitions to discover app stability problems
MediaPlayer提供的常用方法
方法 说明
MediaPlayer 构造方法
create 创建一个要播放的多媒体
getCurrentPosition 得到当前播放位置
getDuration 得到文件的时间
getVideoHeight 得到视频的高度
getVideoWidth 得到视频的宽度
isLooping 是否循环播放
isPlaying 是否正在播放
pause 暂停
prepare 准备(同步)
prepareAsync 准备(异步)
release 释放MediaPlayer对象相关的资源
reset 重置MediaPlayer对象为刚刚创建的状态
seekTo 指定播放的位置(以毫秒为单位的时间)
setAudioStreamType 设置流媒体的类型
setDataSource 设置多媒体数据来源(位置)
setDisplay 设置用SurfaceHolder来显示多媒体
setLooping 设置是否循环播放
setOnButteringUpdateListener 网络流媒体的缓冲监听
setOnErrorListener 设置错误信息监听
setOnVideoSizeChangedListener 视频尺寸监听
setScreenOnWhilePlaying 设置是否使用SurfaceHolder来保持屏幕显示
setVolume 设置音量
start 开始播放
stop 停止播放
MediaPlayer的工作流程是这样的:
ijkPlayer接口
private IjkMediaPlayer ijkMediaPlayer; ijkMediaPlayer = new IjkMediaPlayer(); ijkMediaPlayer.setSurface(this.surface); //surface窗口,我们可以使用 TextureView 将它的Surface传给 // 播放器在准备完成,可以开播时会发出onPrepared回调 ijkMediaPlayer.setOnPreparedListener(onPreparedListener); //监听播放器准备就绪的回调 ijkMediaPlayer.setOnInfoListener(onInfoListener); // 监听播放器各种状态 例如缓冲,渲染中,缓冲结束等等 ijkMediaPlayer.setOnErrorListener(onErrorListener); // 播放器各种错误状态监听,例如协议不支持,视频源非法等等 ijkMediaPlayer.setKeepInBackground(true); //保持屏幕持续点亮 --避免息屏 //处理缓冲,提高播放速度 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1); //dns 清理 ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0); ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer"); ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, ijkMediaPlayer.setDataSource(mVideoUrl); ijkMediaPlayer.prepareAsync(); stop();setDisplay(null);mMediaPlayer.release();---这个很耗时 start();
recyclerview缓存机制
断点日志: