Android下NDK开发的动态库(.so,shared library)增加版本号信息

在Android下面开发,免不了要涉及到C/C++层的开发,这就会涉及到崩溃异常的处理问题。

随着程序的不断升级,更新,会出现多个版本的动态库同时在线上共存的问题,一旦出现崩溃日志,往往不能方便的知道到底是哪个版本出现的崩溃。

传统的Linux,可以通过编译时候指定版本号来处理,最后生成如“libc.so.6”这种形式的文件名,我们可以根据文件名来获得相应的版本信息。遗憾的是,这种命名方式,在Android上面是不支持的

目前的需求主要有三点:

  1. 不依赖文件名,查询到版本号

    版本号写在文件名中,是一个比较方便的方式,但是带来的问题却是,靠不住!文件名可以随意更改,往往传来传去,文件名中的信息就改得面目全非了。

  2. logcat的崩溃日志中能得到版本号

    系统自带的logcat会在进程崩溃的时候,打印出崩溃栈,但是信息非常的精简,只有当前的线程回退栈帧信息(backtrace)以及几个关键寄存器信息,往往不能准确提供有足够的信息。而如果想在客户的设备上面,拿到完整的core-dump信息,只能是呵呵一下了!

  3. C/C++层的版本号变动,不要改动JAVA层的代码

    一方面,如果我们把版本号写在动态库的名字里面,这样会造成每次动态库的升级,JAVA的调用代码都需要变动,小团队还好,大团队,完全不可想象。另一方面,如果是系统框架层的开发,更加悲催,一个文件名的改动,影响到一片,当然,软链接也是个不错的选择,但是这样,常用的APK开发又要折腾一番,免不了一堆的抱怨。

针对上面的需求,我们逐个来提供解决方案:

  • 不依赖文件名,查询到版本号

在任意的C/C++文件中增加如下代码

在Android.mk文件中增加

编译生成的".so"文件使用如下命令即可查询版本号信息:

解释:
上面的代码的目的,是要求GCC在一个名为".SO_VERSION"的段内,记录我们的版本号信息。“unused”属性用于告诉GCC,不要在编译的时候警告这个变量没有被任何代码引用过。
注意事项:
在定义变量"Version"的时候,不要使用"volatile"来修饰。这个关键字影响到了最后生成的段的"PROGBITS"标记位置,这个标记表明了最后加载到内存中的数据是否可修改(我们当然希望这个位置不可修改,如果可写,可能由于越界导致版本号的不准确)。

没有使用"volatile"修饰

使用"volatile"修饰

注意两者的不同,一个属性是"A",一个属性是"WA"。

  • logcat的崩溃日志中能得到版本号,并且C/C++层的版本号变动,不要改动JAVA层的代码

目前对于这个问题的解决方法,是设置代理So。具体操作方式如下(假定我们生成的".so"项目LOCAL_MODULE:=So):

1.修改原来项目中的"JNI_OnLoad","JNI_OnUnLoad"函数,重新命名为 "So_JNI_OnLoad","So_JNI_OnUnLoad" 其他代码不变,并且在"So-jni.h"中对这两个函数进行声明。

2.所有的JNI方法都通过 "JavaVM->RegisterNatives" 方法进行动态注册。

3.建立SoStub-jni.cpp,代码如下:

4.原工程的"LOCAL_MODULE"修改为"LOCAL_MODULE:=So_1_0_3"(版本号根据实际情况调整即可

5.修改Android.mk,增加如下内容

6.修改JAVA层的调用代码

为:

解释:

由于logcat打印的崩溃栈,信息极少,因此我们只能采取这种折中的办法,这样设置之后,崩溃栈中会打印出"libSo_1_0_3.so"这样的字样,我们就可以知道版本号了。

JS处理相对路径

遇到引擎不能处理相对路径的问题,写了一个简单的相对路径转绝对路径的函数,留下备用:

原理很简单,只支持/,且遇到错误不能自动处理

Android Studio(JAVA) 编译警告:使用了未经检查或不安全的操作

在编译Android Studio(JAVA)程序时发生了如下的警告:

使用了未经检查或不安全的操作
要了解详细信息,请使用 "-Xlint:unchecked" 重新编译。

  • 如何设置Android Stuido开启 "-Xlint:unchecked"

修改build.gradle

增加

修改后的如下:

  • 警告信息的处理例子

包含-Xlint:unchecked警告的代码

消除警告后的代码如下:

同样的方法适用于"-Xlint:deprecation"。

svnrdump dump 实现 SVN 库的远程导出

svnrdump dump 命令必须 在 SVN 1.7版本以上提供的用于远程dump SVN库的命令.

以导出libyuv的svn库为例:

可以在这里下载已经DUMP完成之后的版本。目前的版本号是1444。

恢复DUMP文件到Subversion工程,请参考 Could not open the requested SVN filesystem

Debian和OpenMediaVault在命令行下设置更新源

很多时候我们比较纠结的问题是,“该把哪个Debian镜像发布站点加入source.list文件?”。

Ubuntu的图形界面中有一个测试工具,命令行下面的Debian也有一个现成的程序:netselect

安装netselect

不带参数运行它时会显示它的帮助信息。运行它时加上以空格分隔的镜像主机列表,它会返回一个分值和列表中的一个主机名。这个分值通过评估ping time和hopsnumber(一个网络请求报文到达目标主机所经过的转发主机的个数)得出,它与镜像站点预计下载速度成反比(数值越小越好)。返回的主机名是主机列表中得分最低的那个(查看列表中所以主机的得分情况可使用-vv选项)。看出下的例子:

它表示,在netselect后列出的所有主机中,http://mirrors.163.com/debian/是下载速度最快的主机,其得分为5。

注意,最近163的服务器不知道发生了何种故障,导致各种更新失败,尽管测试的结果是163更快,但是我们建议还是使用阿里云的服务器。

把netselect找到的连接速度最快的镜像站点手工加入/etc/apt/sources.list文件.

最新版本的netselect软件包包含了netselect-apt脚本,它使上述操作自动完成。只需将发布目录树做为参数(默认为stable)输入,sources.list文件就会生成速度最快的main和non-US镜像站点列表,并保存在当前目录下

对于OpenMediaVault用户还是手工修改配置文件好了,主要是上面的工具生成的比较简略

JS常用方法封装

做项目是遇到一个封装的不错的Util类,写一下,长期备用:

CMD标准

Ubuntu 12.04 + Apache2.2.22搭建SPDY服务器

SPDY是Google开发的基于传输控制协议(TCP)的应用层协议,该协议规定在一个SPDY连接内可以有无限个并行请求,服务器可以主动向客户端发起通信向客户端推送数据,通过请求优化、预加载、压缩HTTP 来达到加速的目的。

对用记而言,SPDY是基于SSL加密,它可以让网络访问更安全,用户隐私更加得到保护。对站长而言,SPDY在降低连接数目的同时,还使服务器上每个客户端占用的资源减少,从释放出更多内存和CPU ,让网站的浏览速度提升不少。

SPDY协议已经被Chrome、Firefox、Opera、IE 11以上支持,用户在访问使用SPDY协议加载的网站几乎感觉不到与普通的Https页面访问有何不同,而SPDY带来的页面加载速度提升和服务器性能优化确是有十分重要意义的。

具体的操作步骤如下:

  • 启用Apache2的HTTPS支持

参考 UBUNTU 12.04 下 APACHE 2.2.22 开启 HTTPS

  • 下载Apache2的mod_spdy模块

官网:https://developers.google.com/speed/spdy/mod_spdy/
由于众所周知的原因,本站提供下载(2015-11-6版本)
mod_spdy 64-bit .deb (Debian/Ubuntu)
mod_spdy 32-bit .deb (Debian/Ubuntu)

  • 安装mod_spdy模块(本站是64位系统)

  • 重启Apache2

  • 验证

目前验证貌似没有起作用啊!目前最新的chrome已经没办法进行验证了,主要是由于HTTP/2已经发布,Google放弃了spdy,转而支持HTTP/2,还是静待新版本的HTTP/2吧。

  • 卸载

  • 参考链接

Linux Mint + Apache2.2搭建SSL/HTTPS/SPDY服务器
https://developers.google.com/speed/spdy/mod_spdy/

IScroll的使用-方向键绑定&自定义滚动条样式

之前在webkit上开发一个滚动控件,需要完成的是一段文字,上下键可以滚动,且自定义滚动条。第一想法就是浏览器原生overflow:scroll,且webkit支持自定义滚动条样式:

webkit自定义滚动条样式:

后来换了个引擎,发现其他引擎不支持自定义滚动条,那就满足不了UED的要求了。来同事推荐使用IScroll,用了一下,确实比较方便,与平台无关,可操作的属性还有性能都很理想,记录一下:

首先看官方文档 https://iiunknown.gitbooks.io/iscroll-5-api-cn/content/versions.html

github地址:https://github.com/cubiq/iscroll

demo:http://cubiq.org/dropbox/iscroll4/examples/simple/

直接拿demo中的iscroll.js套到自己的工程上,一个段落就是一个li,new 一下就完事了,滚动拖动也很happy。然后发现,我按上下方向键没有响应。

IScroll按键事件绑定:

查源码看iscroll的事件处理,都在handleEvent函数里面

根本就没有keyEvent,看来偷懒是不行的,官方文档看一下,原来iscroll有5个版本,各自平台都是不一样的,demo中这个估计是移动平台用的iscroll-lite版本,移动平台根本不鸟方向键的。

去github上down下来源码,找了找,build目录下,5个版本都有。用最原始的common版本,这个版本的handleEvent就丰富多了:

然后套用上去,可以支持方向键了。中间遇到两个小问题,第一个是按键一直没反应,检查下是z-index太小,keyEvent被上层元素拿走了;第二个是只有在#warpper拿到focus的时候才响应按键,但我用的引擎不支持focus,这个也不难,页面强行绑定handleEvent:

然后整个页面随便按什么键,都可以响应了。接下来就是滚动条样式的问题了,这个也简单,跟着官方文档&样例走就行

http://lab.cubiq.org/iscroll5/demos/styled-scrollbars/

关键步骤有三个:

1.option

设置了scrollbars: 'custom',在页面的Elements就可以找到

<div class="iScrollVerticalScrollbar iScrollLoneScrollbar" ></div>

里面还包含了

<div class="iScrollIndicator" ></div>

第一个是滚动区域,第二个是滚动条。拿到Element就好办了,css给定样式:

大功告成!

当然,IScroll不止这点功能,官方文档后面还有无限滚动等高级用法,以后用到再添加。

WordPress使用WP-PostViews实现网站上显示文章的浏览量

WordPress的使用很方便,但是文章的点击浏览量默认是没有的,本文介绍用WP-PostViews实现网站上显示文章的浏览量的功能。效果如下图所示:WP-PostViews_Settings

  • 安装WP-PostViews插件

在插件界面中安装WP-PostViews插件,并且启用插件。

  • 修改主题文件(Twenty Fourteen)

修改content.php,找到如下代码:

在后面添加:

修改后的结果如下:

  • 修改主题文件(Twenty Fifteen)

修改content.php,找到如下代码:

在后面添加:

修改后的结果如下: