faywong 发布的文章

方法如下:

在自定义的WebChromeClient中实现如下方法(主要是为了保证不同android版本上的兼容性):

```java
public void openFileChooser(final ValueCallback uploadMsg)
public void openFileChooser(ValueCallback uploadMsg, String acceptType)
public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture)
```
并配置proguard保证其不被混淆掉。

在openFileChooser中使用如下Intent调用系统文件浏览器:

```java
private Intent createDefaultOpenableIntent(final Context ctx) {
// Create and return a chooser with the default OPENABLE
// actions including the camera, camcorder and sound
// recorder where available.
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");

Intent chooser = createChooserIntent(ctx, createCameraIntent(), createCamcorderIntent(),
createSoundRecorderIntent());
chooser.putExtra(Intent.EXTRA_INTENT, i);
return chooser;
}

```
然后:

```java

startActivityForResult()

```
在主Activity的onActivityResult()中

调用ValueCallback对象的onReceiveValue()方法中将选择文件的Uri传回。

但是问题还是来了,这样做了之后在4.4系统上WebView不会回调openFileChooser方法导致没法显示出选择文件的Activity。

另外对于选择文件的应用也不能假定所有的Android系统上都有。

所以终极解决方案就是拥有自主可控的WebView。

PostgrepSQL 9.4开始支持了jsonb数据类型,从而支持了一部分nosql特性。今天使用了下,简要记录下:

记得在pgadmin中验证下postgresql的版本号:

```sql

SELECT version();

```
确认是9.4以上。

确认之后可以在SQL终端继续感受下:

```sql
SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
```
创建一个jsonb类型的字段:

```sql

CREATE TABLE mobile_analysis
(id serial PRIMARY KEY,
datadoc jsonb,
create_at TIMESTAMP WITH TIME ZONE default current_timestamp);

```
其中datadoc是我想存为json格式的字段的名称,为了支持后续的检索,为其创建索引:

```sql

CREATE INDEX idx_mobile_analysis ON mobile_analysis USING gin (datadoc jsonb_path_ops);

```
其中的jsonb_path_ops是为了支持对jsonb字段的值进行检索,条件过滤(比如包含有特定的key-value对的记录)所必需的。

插入一条测试数据:

```sql

INSERT INTO mobile_analysis(datadoc)
VALUES ('{"a": 1, "b":2, "d": "string_val"}');

```
通过包含条件查询之:

```sql

SELECT * FROM mobile_analysis WHERE datadoc @> '{"a":1}'

```
更多的关于json/jsonb类型的函数和操作符的资料请见这里。

有的同学在使用 git 时会不小心本地分支merge了远端的公共分支(通过 git pull ),我找了篇文章帮助大家学会 pull 的时候直接 rebase

[http://gitready.com/advanced/2009/02/11/pull-with-rebase.html](http://gitready.com/advanced/2009/02/11/pull-with-rebase.html)

其实很简单,对应的命令行是:

```bash
git pull --rebase  
```

由于 merge 提交会湮灭掉一些原始 commit 导致 rebase 时带来混乱,同时 merge 提交的 commit message 本身没有什么额外有价值的信息,我个人关于 merge 提交的经验是:

>如果你的角色是scm,代码集成者,多个分支隔离开发很长时间之后的合并建议使用merge;每天持续开发中的数量不多的提交都最好使用rebase,这样可以让提交记录尽量保持线性和整洁,进而方便代码的集成和追踪。

![](/uploads/2016_01_21_01.png)

尽管现在诞生的高级语言里边有了什么STM,协程,绿程的概念,但写代码总会遇到现实(商业级平台都不会用很新的东西)的多线程的问题。

比如有时候你需要同步的获取在另一个线程执行的代码的结果,在android里这种场景下ConditionVariable就非常好用了。

```java
if (Looper.myLooper() != Looper.getMainLooper()) {

final ConditionVariable completed = new ConditionVariable(); // 构造一个条件变量

view.runOnUiThread(new Runnable() {

@Override
public void run() {
try {
doSomeThingInUiThread(); // 将期望在另外线程做的事post出去
} finally { // finally很重要,防止运行时异常远跳转将ConditionVariable忘了open
completed.open(); // 事情办完了,notify到另外线程
}
}
});
completed.block(TIMEOUT_WAIT_UI); // 等着另外线程做的事完成,同时支持设置超时
} else {
doSomeThingInUiThread();
}
```

当然了以上是很简单的一个场景,使用ConditionVariable非常方便且够用。对于复杂的多线程之间的协同还是使用标准的条件变量结合lock + while 循环检查。

在一些新语言中有非常丰富的并发编程原语(future, delay, promise),特别是协程让我们用代码自主的确定代码流之间的协作关系而不是被动的作为OS调度器的奴隶,来支撑一些并行需求。

### [v8](https://developers.google.com/v8/)

支持jit,性能好,生态大,sdk 支持面向对象编程,上手容易,代码能够保持优雅;调试协议能被 chrome 支持;同时由于 [JIT](https://en.wikipedia.org/wiki/Just-in-time_compilation) 会在运行时生成额外的代码段,在iOS平台上发布时容易受限

### [Duktape](http://duktape.org/)

性能一般,但代码体积小,使用标准c开发,方便集成和嵌入其他项目;支持ES5.1的标准,文档和社区不错,开发起来经常需要掰着手指在那里计算堆栈入了多少次,出了多少次,刚开始会有点折磨;其作者对于开发和维护非常积极,基本上要求的特性只要社区呼声较高,他都会考虑添加进去,个人开发能力极强

Duktape 使用方面的其他文章请见标签 [Duktape](/tags/Duktape.html)

### [v7](https://github.com/cesanta/v7)

v7 性能是 non-JIT 引擎中较好的,但是对于ES规范的覆盖上不够,成熟度一般

### [Rhino](https://www.mozilla.org/rhino/)

rhino的爹是Mozilla,用java编写,可以在android上不用写JNI代码,容易集成,性能也不错,项目历史很悠久,成熟度很高(访问不了其官网的,请前往 [Github](https://github.com/mozilla/rhino)),但是存在很多不适合在线上环境中使用的特点:

* 在实际开发中,只要在java层bridge实现掉document、window之类对象后,这种对象的属性读写和方法调用都全部落到了java层,就在js域连document.xxx = yyy;这样的写法都不支持了,查完它的官方maillist都没办法实现。

* 在js侧用toString, print, JSON.stringify之类的方法容易将java层所有的方法和字段给反射出来,会有安全隐患

### 没事为什么要撸那么多js引擎

移动互联网年代客户端开发最痛苦的在于动态性,需求总有要变的时候,这时候一门灵活、能通过网络下载到客户端就地执行的语言就很重要了。而目前最合适的那门语言便是javascript。