万丈红尘千杯酒,
千秋霸业一壶茶。
在使用 Android Studio 时,如果出现语法错误(例如少了分号), Android Studio 会通过红色波浪线提示你,并且右侧滚动条上也会打上红色标识。可是,红色波浪线太弱而不能被察觉,滚动条的红色标识定位也不是很准。导致都难以定位到错误位置。但其实 Android Studio 提供了快捷的方式定位到错误处:
Navigate -> Next Highlighted Error (快捷键: F2)
已经编译安装好的nginx,添加未被编译的模块:
cd ~/www/src/nginx-1.10.2
查看nginx原有的模块:
/usr/local/nginx/sbin/nginx -V
原有 configure 参数输出在 configure arguments: 的后面,如:
--prefix=/usr/local/nginx
运行 configure 命令(在原有参数后补充新模块参数),如:
./configure --prefix=/usr/local/nginx --with-http_ssl_module
运行 make 命令 (不要 make install)
备份原本安装好的 nginx:
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
将刚刚编译好的 nginx 覆盖掉原有的 nginx:
cp ./objs/nginx /usr/local/nginx/sbin/
启动 nginx
从远处传输文件到本地:
scp -r name@ip:path/filename/ target
创建用户:
CREATE USER 'username'@'host' IDENTIFIED BY 'password';
授权:
SHOW GRANTS FOR 'username'@'host'; // 查看授权
GRANT privileges ON dbname.tablename TO 'username'@'host'; // 授权
REVOKE privilege ON dbname.tablename FROM 'username'@'host'; // 取消授权
设置与更改用户密码:
SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword');
SET PASSWORD = PASSWORD("newpassword"); // 针对当前登录用户
删除用户:
DROP USER 'username'@'host';
使用 ApplicationContext 去 startActivity 在某些 Android 版本下必须要加上 FLAG_ACTIVITY_NEW_TASK,否则会 crash。 详情请见 ContextImpl.startActivity(Intent, Bundle) 。(注:API 23 以下 和 API 23 及其以上的实现并不一样)
当我们想 TextView 在上使用跑马灯效果时, 我们会发现简单的设置 android:ellipsize="marquee" 和 android:singleLine="true" 并不生效。我们还需要主动调用 setSelect(true) 才行。
Dialog 的创建不能使用 ApplicationContext,会 crash。
RecyclerView 的 LinearLayoutManager 提供了两个比较好玩的 API :reverseLayout 和 stackFromEnd
View.getWindowVisibleDisplayFrame(Rect rect) :
作用:返回当前 view 所 attach 的 window 的可视区域的大小
影响因子:statusBar(rect.top)、navigationBar(rect.bottom)、虚拟键盘(rect.bottom)
具体表现:
如果 window 不与 statusBar、navigationBar 和虚拟键盘重叠,那么 rect.top = 0,rect.bottom = screenRealHeight - navigationBarHeight
rect.top = 全屏 ?0 : (widow.layoutparam.height == MATCH_PARENT ? 状态栏高度 : window 与状态栏高度重叠的高度)
rect.bottom(键盘升起) = widow.layoutparam.height == MATCH_PARENT ? screenRealHeight - navigationBarHeight - keyboardHeight :screenRealHeight - navigationBarHeight - 键盘与window重叠区域的高度
rect.bottom(键盘未升起) = screenRealHeight - navigationBarHeight
当我们的 ListView 拥有多着类型的 itemView 时,一定要注意 adapter.getViewTypeCount 的维护,特别是后期添加类型时,经常忘记更改 getViewTypeCount,因此就会出现如下 crash :
如果对于老手,可能快速反应出问题的关键点,但对于新手或者不熟悉 ListView 多类型的开发者,就会有点不知所措了。对于 RecyclerView,就不会有这个问题了。
查看提交代码的行数变化:
git log --author="NAME" --since=1.week.ago --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }’
当 ListView 的 itemView 的子 view 存在点击事件或者 clickable 为 true 时, 那么点击 itemView 不会触发 ListView 的 mOnItemClickListener;反之,如果你不想 ListView 的 mOnItemClickListener 被触发,你可以设置 itemView.setClickable(true)
View 的 detach 和 attach 可能会因为 Animation 而变得混乱,不经意间就造成 View 假死,例如:
mView.startAnimation(disappearAnimation);
ViewGroup parent = (ViewGroup) mView.getParent();
parent.removeView(mView); // 移除 view 时伴随动画
//...
parent.addView(mView); // 动画未结束时又将 view 加回来
mView.startAnimation(appearAnimation);
现象:mView 无法接收事件,使用 uiautomatorviewer 时也无法查看其信息
原因:当 mView.getAnimation() != null 时,parent.removeView() 并不会detach 掉 mView,而是暂时将 mView 放入的成员变量 mDisappearingChildren 中,在 parent.dispatchDraw() 中当 mView.getAnimation() != null 且 动画已经结束时,才执行 mView 的 detach逻辑。但是当动画中途执行 mView.StartAnimation(newAnimation) 时, parent.dispatchDraw() 中 mView.getAnimation() 所获取的对象已经变了,那么 detach 的时机也就变了。
上述代码的执行顺序大致为:mView.startAnimation(disappearAnimation) -> parent.removeView -> mDisappearingChildren.add(mView) -> parent.addView -> mView.attach -> mView.startAnimation(appearAnimation) -> appearAnimation.end -> mDisappearingChildren.remove(mView) & mView.detach。最终 mView 处于 detach 状态,故而 View 会假死。
现实场景:当 fragment A 切换到 fragment B 时,如果转场动画还没结束时就快速按返回键使 fragment B pop 掉,最终会造成页面假死在 fragment A 上。QMUI 上就遇到这个问题,具体解决措施也可参考参考
MIUI8 USB开发过程中禁用装包提示:设置->更多设置->开发者选项->关掉MIUI优化,重启,再进入安全中心->授权管理->右上角的小齿轮->关掉USB安装管理
ListView、GridView 在 getView 时要避免调用 View 的 setLayoutParam。因为 setLayoutParam 会触发 requestLayout 导致 ListView 刷新 layout,而 ListView 重新 layout 时又可能触发 getView,导致多次甚至循环 layout。这种循环 layout 会产生以下几个现象:
当 Activity 设置了 android:windowIsTranslucent 后,其屏幕旋转取决于透明 Activity 背后的那个 Activity,我们可以把透明 Activity 当做一种特殊的 Dialog,这样大致可以理解 Android 开发团队为何要这样做了。如果我们需要动态修改旋转特性,我目前有两种方案:
当 Activity 设置了 android:windowIsTranslucent 或者 android:windowIsFloating 后,默认情况下 onConfigurationChanged 就不再被调用到,因为这种情况下会触发透明 Activity 后的那个 Activity 的绘制(耗费性能),必要时候需要添加 android:screenOrientation="sensor" 强制使旋转生效。
C++11新特性:
如何检测某一事件是否被支持:
ViewPager 的 PagerAdapter 存在一个方法 setPrimaryItem,在 item 被认为是 “primary” 时会被调用。但是其在 ViewPager.onMeasure 时也会调用到,如果使用不当,可能会造成死循环。
App 的 Context 的数量 = Activity 的数量 + Service 的数量 + 1(Application)