Android: 9-patch的夜间模式
https://www.evernote.com/l/ABCVzpSbJs1HoKym6kJDBZQsyMlFtgXKYpM
https://www.evernote.com/l/ABCVzpSbJs1HoKym6kJDBZQsyMlFtgXKYpM
https://www.evernote.com/l/ABC9oWR2d7xBaK-bic2LbgXHmwIsthq2-HI
https://www.evernote.com/l/ABDmk4yr90FNi6-Pa69oLDK291tym7e00qE
在猿题库工作一年多, 新功能做了不少, bug 也改了许多, 近期开始做更多的优化工作. 本篇博客的内容来自"错题锁屏"功能的优化. 我们 2014 年 9 月开始做"错题锁屏"功能, 希望增加曝光, 提高存留. 开发该功能的同学现在已经结束实习出国工作了, 但做这个功能的时候我就知道坑很多, 而且上线前为了避免风险留了一些坑没改. 上线后, 发现该功能比较受欢迎, 所以又有了多次拉锯式的修改, 不过对于锁屏本身的坑并没有填. 关于如何防止锁屏进程被杀, 我可能会开另外一篇博客来说明, 不过其实你也可以逆向工程我们的 apk 自己去看. 还有就是错题锁屏变成一个独立进程之后, 进程间共享数据变成了一个新的大坑… 由于我们一开始就不想把错题锁屏做得很暴力, 所以虽然禁用了 Back 键(按 Back 键不能退出锁屏), 却还是保留了按 Home 键退出的可能性, 避免用户因为答不对题而无法解锁(我们可能低估用户了). 于是有一个问题, 按 Home 键退出锁屏之后, 用户可以在"最近使用"中重新打开锁屏界面, 而我们只想让用户在"最近使用"中看到猿题库本身. 我开始寻找如何在用户按 Home 键时让锁屏界面自己把自己 finish 掉的方法. 首先查到的方法是 onUserLeaveHint, 按 Home 键时确实会调用这个函数. 不过遇到的问题也很坑: 当有其它锁屏, 甚至 QQ 弹窗(实际上也是用类似锁屏的方法实现的)出现时, 我们的锁屏可能被挤掉(onUserLeaveHint 被调用). 然后开始寻找能够捕获 Home 键的方法: override onKeyDown, 不过 no longer works as of 4.0, 这里给出了完整的代码 这篇 vote 比较少的文章其实离最终答案很近了, 不过因为 vote 太少, 我一开始没有相信它… 中文网络上看起来有更多人搞过这个问题: 文章 A B C 大同小异, 这里分析得更详细一些. 其中 B 的代码更漂亮一些, 我试过可行 (Android4.+) 可行之后, 我发现又掉到了坑里: 即使 finish 掉了, 用户还是可以在最近使用中重新打开锁屏界面!!! ...
Manifest 弹出键盘 android:windowSoftInputMode 控制弹出键盘 stateHidden 为刚进入 activity 时不显示键盘 控件 EditText 与弹出键盘 在 xml 中设置 android:inputType, 常用的有: default, 中文手机会弹出中文输入法, 并切换到默认输入模式(通常是中文模式) phone, 电话号码键盘, 不过我们通常还是会用 number 彻底限制只能输入数字 textEmailAddress, 虽然名字是 email, 但是也可以输入电话号码 java 中可以 setInputType, 对应的 type 在 InputType 找到: 比如 textEmailAddress 对应 TYPE_TEXT_VARIATION_EMAIL_ADDRESS 注意 textPassword 对应 TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD 详见 官方文档 工具 sleep SystemClock.sleep 不会抛出 InterruptedException, 同时也无法 thread.interrupt Thread.sleep 则正相反 线程 UI 线程 UI 控件不是线程安全的, 所以只能在 UI 线程上操作 Activity.runOnUiThread View.post/postDelayed Handler AsyncTask doInBackground 在 worker 线程 onPre/PostExecute 和 onProgressUpdate 在 UI 线程 WebView 使用 HttpClient 的 cookie /** * @param url - 形如 http://xxx.domain.com/yyy/zzz.z?mmm=nnn * @param cookie - 从 HttpClient 取得的 cookie */ public static void synCookies(Context context, String url, Cookie cookie) { CookieSyncManager.createInstance(context); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); // 这句可能可以不要 String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain(); cookieManager.setCookie(url, cookieString); CookieSyncManager.getInstance().sync(); }
安装 下载安装后, 需要更新到最新版本 不更新可能会遇到一些奇葩问题 如果能直接更新或者翻墙更新的, 请直接更新 不能更新的, 请参考下列文章手动更新 http://www.cnsecer.com/842.html http://blog.csdn.net/hil2000/article/details/11395485 关键命令 java -classpath AI-<old-edition>-<new-edition>-patch-<os>.jar com.intellij.updater.Runner install . 新建项目 新建一个项目时, 视选择的 SDK 版本, 可能会失败, 原因是包不全 打开 SDK Manager, 勾选需要的包, 点击 Install X package[s]… 注意: 接受协议时可能需要在弹出的对话框里逐个接受, 才能一并下载 模拟器 以下问题仅限于 windows, Mac 用户可以直接放弃模拟器… 运行模拟器失败, 需要把 X盘/.android/avd 拷贝到 C盘/用户目录/.android 下 运行模拟器慢, 需要下载和安装 intel x86 emulator, 创建 avd 时也要选这个 用 SDK Manager 下载 intel x86 emulator 和对应的 rom 注意: 下载 emulator 后需要安装, 可执行文件在 sdk/extras/intel 中 数据目录 Android Studio 目前还不太稳定, 偶尔折腾, 甚至需要把数据目录清空 下面的内容摘自 Intellij 官网, 只要把路径换成 AndroidStudioPreview 即可 Mac ~/Library/Application Support/IntelliJIdeaXX contains the catalog with plugins. ~/Library/Preferences/IntelliJIdeaXX contains the rest of the configuration settings. ~/Library/Caches/IntelliJIdeaXX contains data caches, logs, local history, etc. These files can be quite significant in size. 9.0+ ~/Library/Logs/IntelliJIdeaXX contains logs Windows ~\.IntelliJIdeaXX\config that contains user-specific settings. ~\.IntelliJIdeaXX\system that stores IntelliJ IDEA data caches. Update@2015.04.13: Android Studio 在升级到 1+ 之后奇葩问题少多了 Update@2016.03.10: 模拟器建议使用 Genymotion