Android:flags:value

最近用到了Android flag的机制,把Android现在所有的flag列出来,供参考。

FLAG_GRANT_READ_URI_PERMISSION 0x00000001
FLAG_GRANT_WRITE_URI_PERMISSION 0x00000002
FLAG_FROM_BACKGROUND 0x00000004
FLAG_DEBUG_LOG_RESOLUTION 0x00000008
FLAG_EXCLUDE_STOPPED_PACKAGES 0x00000010
FLAG_INCLUDE_STOPPED_PACKAGES 0x00000020
FLAG_GRANT_PERSISTABLE_URI_PERMISSION 0x00000040
FLAG_GRANT_PREFIX_URI_PERMISSION 0x00000080
自定义 0x00000x00
自定义 0x00001000
FLAG_ACTIVITY_RETAIN_IN_RECENTS 0x00002000
FLAG_ACTIVITY_TASK_ON_HOME 0x00004000
FLAG_ACTIVITY_CLEAR_TASK 0x00008000
FLAG_ACTIVITY_NO_ANIMATION 0x00010000
FLAG_ACTIVITY_REORDER_TO_FRONT 0x00020000
FLAG_ACTIVITY_NO_USER_ACTION 0x00040000

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 0x00080000
FLAG_ACTIVITY_NEW_DOCUMENT 0x00080000

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY 0x00100000
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 0x00200000
FLAG_ACTIVITY_BROUGHT_TO_FRONT 0x00400000
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 0x00800000
FLAG_ACTIVITY_PREVIOUS_IS_TOP 0x01000000
FLAG_ACTIVITY_FORWARD_RESULT 0x02000000
FLAG_ACTIVITY_CLEAR_TOP 0x04000000

FLAG_ACTIVITY_MULTIPLE_TASK 0x08000000
FLAG_RECEIVER_NO_ABORT 0x08000000

FLAG_RECEIVER_FOREGROUND 0x10000000
FLAG_ACTIVITY_NEW_TASK 0x10000000

FLAG_RECEIVER_REPLACE_PENDING 0x20000000
FLAG_ACTIVITY_SINGLE_TOP 0x20000000

FLAG_RECEIVER_REGISTERED_ONLY 0x40000000
FLAG_ACTIVITY_NO_HISTORY 0x40000000

Node.js源码学习-模块

Node.js底层有三个重要部分

node

libuv 建立事件循环

v8 引擎以及JS/C++对象转换

node提供的模块 fs os net process等

libuv是一个神器,事件循环,适合状态机驱动的架构,单独学习。

v8的请看google的官方API文档。

今天主要看一下node的模块。

 

1.js2c.py

node内置了很多js文件,包括主程序 src/node.js和模块文件lib/*.js。js2py是把每一个js文件都生成一个源码数组,存放在node_natives.h中。

node_native

node_native.h中,每个js文件对应一个数组,源码以const char数组的形式存放。

 

node_native在映射完毕后,变成了这样一个数组。

2.node_javascript.cc

node_javascript.cc include了node_native.h,并提供两个方法:

MainSource(),只有一句

return OneByteString(env->isolate(), node_native, sizeof(node_native) - 1);

返回node_native映射的js文件,即node.js,转换成了一个v8::handle类型。node_native_1

 

 

图:node_native,node.js映射后的数组。

DefineJavaScript(env, target)

将所有js文件映射到Object型的target(不包括node.js)

target->Set(name, source)

综上,node_javascript.cc做了两件事,返回node.js的v8::handle,

返回lib/*.js的Object,{name: v8::handle, name: v8::handle .....}

现在所有js文件都被转换成了v8::handle。

3.node.cc

node.cc是nodejs的main文件,这里我们先认识一个node世界中的风云人物,process。

 

 

在node.cc的CreateEnvironment函数中,process出生了,下面我们从源码看看process是个什么?被赋予了哪些属性?

从上面这段代码可以看出process的原始属性,FunctionTemplate,很明显,是js里的一个function,function的name为process。

现在JS世界中已经多了一个叫process的function,那么它是在哪里成长的呢?

 

在node.cc的LoadEnvironment函数中,

运行MainSource

拿到了node.js的返回f_value,即node.js函数,入参为process的闭包函数,

(function(process) {})

验明正身,执行node.js闭包函数,最后一句做JS的同学看着肯定很眼熟,这不就是

(function(process){}).call(global, process)

 

4.fs.js

这里通过一个fs模块的创建与加载,来展示process呼风唤雨的能力。

首先规规矩矩的加载了几个模块,然后突然出现了binding

Binding在node.cc中实现

主要逻辑为,查看cache中是否有这个模块,如果没有就新建一个。

新建模块:如果存在builtin,则使用nm_context_register_func方法注册到cache中,如果是常量,cache中注册常量,如果是natives,绑定所有lib/*.js。

在fs中,process.binding找到了fs,是一个builtin模块。这个模块在node_file.cc中实现,最后通过NODE_MODULE_CONTEXT_AWARE_BUILTIN注册到builtin。

Binding函数完成了js上调用C++模块。

 

5.node.js

node.js中通过一个NativeModules来管理js模块,

 

process.binding('natives'),将所有内置js模块绑定到_source上。

之后可以通过require方法来拿到这些模块。

先检查cache,如果cache没有,就在process.moduleLoadList中增加一个,然后缓存,执行.

缓存就是把模块放到_cache中,compile函数

通过C++模块contextify运行了这段js。

 

 

libuv学习

libuv 是重写了下libev,封装了windows和unix的差异性。
libuv的特点
非阻塞TCP套接字 socket?
非阻塞命名管道
UDP
定时器
子进程 fork?
通过 uv_getaddrinfo实现异步DNS
异步文件系统API uv_fs_*
高分辨率时间 uv_hrtime
正在运行程序路径查找 uv_exepath
线程池调度 uv_queue_work
TTY控制的ANSI转义代码 uv_tty_t
文件系统事件支持 inotify ReadDirectoryChangesW kqueue 马上回支持 uv_fs_event_t
进程间的IPC与套接字共享 uv_write2

事件驱动的风格:程序关注/发送事件,在事件来临时给出反应。
系统编程中,一般都是在处理I/O,而IO的主要障碍是网络读取,在读取的时候是阻塞掉的。标准的解决方案是使用多线程,每一个阻塞的IO操作被分配到一个线程。当线程block,处理器调度处理其他线程。
libuv使用了另一个方案,异步。操作系统提供了socket的事件,即使用socket,监听socket事件即可。

libuv简单使用 创建一个loop,关闭loop。
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>

int main()
{
uv_loop_t *loop = malloc(sizeof(uv_loop_t));
uv_loop_init(loop);

printf("hello, libuv");

uv_run(loop, UV_RUN_DEFAULT);

uv_loop_close(loop);
free(loop);

return 0;
}

如果只需要一个loop的话,调用uv_default_loop就可以了。
tips:Nodejs中使用了这个loop作为主loop。
uv_loop_t *loop = uv_default_loop();

uv_run(loop, UV_RUN_DEFAULT);

uv_loop_close(loop);

Error
初始化或同步函数,会在执行失败是返回一个负数,可以通过uv_strerror、uv_err_name获得这个错误的名字和含义
I/O函数的回调函数会被传递一个nread参数,如果nread小于0,也代表出现了错误。

Handle & Request
libuv的工作建立在事件的监听上,通常通过handle来实现,handle中uv_TYPE_t中的type指定了handle监听的事件。
在uv.h中可以找到handle和request的定义
/* Handle types. */
typedef struct uv_loop_s uv_loop_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tcp_s uv_tcp_t;
typedef struct uv_udp_s uv_udp_t;
typedef struct uv_pipe_s uv_pipe_t;
typedef struct uv_tty_s uv_tty_t;
typedef struct uv_poll_s uv_poll_t;
typedef struct uv_timer_s uv_timer_t;
typedef struct uv_prepare_s uv_prepare_t;
typedef struct uv_check_s uv_check_t;
typedef struct uv_idle_s uv_idle_t;
typedef struct uv_async_s uv_async_t;
typedef struct uv_process_s uv_process_t;
typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_fs_poll_s uv_fs_poll_t;
typedef struct uv_signal_s uv_signal_t;

/* Request types. */
typedef struct uv_req_s uv_req_t;
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_getnameinfo_s uv_getnameinfo_t;
typedef struct uv_shutdown_s uv_shutdown_t;
typedef struct uv_write_s uv_write_t;
typedef struct uv_connect_s uv_connect_t;
typedef struct uv_udp_send_s uv_udp_send_t;
typedef struct uv_fs_s uv_fs_t;
typedef struct uv_work_s uv_work_t;

/* None of the above. */
typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_dirent_s uv_dirent_t;

handle是持久化的对象。在异步操作中,相应的handle有许多关联的request。
request是短暂性的,通常只维持一个回调的时间,一般对应handle的一个IO操作。request用来在初始函数和回调函数中传递上下文。
例如uv_udp_t代表了一个udp的socket,每一个socket的写入完成后,都有一个uv_udp_send_t被传递。

handle的设置
uv_TYPE_init(uv_loop_t*, uv_TYPE_t);

一个idle handle的使用例子 观察下它的生命周期
#include <stdio.h>
#include <uv.h>

int counter = 0;

void wait_for(uv_idle_t * handle)
{
counter++;

if (counter > 10e6)
{
uv_idle_stop(handle);
}
}

int main()
{
uv_idle_t idler;

uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for);

printf("Idle......");

uv_run(uv_default_loop(), UV_RUN_DEFAULT);

uv_loop_close(uv_default_loop());

return 0;
}

参数传递
handle和request都有一个data域,用来传递信息。uv_loop_t也有一个相似的data域。

文件系统
简单的文件读写是通过uv_fs_*函数族和与之相关的uv_fs_t结构体完成的。
系统的文件操作是阻塞的,所以libuv在线程池中调用这些函数,最后通知loop。

如果没有指定回调函数,文件操作是同步的,return libuv error code。
异步在传入回调函数时调用,return 0。

获得文件描述符
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb);
关闭文件描述符
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
回调函数
void callback(uv_fs_t* req);
还有uv_fs_read uv_fs_write uv_fs_t构成了基本的文件操作

流操作使用uv_stream_t,比基本操作方便不少
uv_read_start uv_read_stop uv_write
流操作可以很好的配合pipe使用
pipe相关函数
uv_pipe_init uv_pipe_open uv_close

文件事件
uv_fs_event_t uv_fs_event_init uv_fs_event_start

网络
uv_ip4_addr ip为 0.0.0.0表示绑定所有接口 255.255.255.255是一个广播地址,意味着数据将往所有的子网接口发送,端口号0表示由操作系统随机分配一个端口
tcp
TCP是面向连接的字节流协议,因此基于libuv的stream实现
uv_tcp_t
服务器端创建流程
uv_tcp_init 建立tcp句柄
uv_tcp_bind 绑定
uv_listen 建立监听,当有新的连接到来时,激活调用回调函数
uv_accept 接收链接
使用stream处理数据以及与客户端通信

客户端
客户端比较简单,只需要调用uv_tcp_connect

udp
UDP是不可靠连接,libuv基于uv_udp_t和uv_udp_send_t
udp的流程与tcp类似

libuv提供了一个异步的DNS解决方案,提供了自己的getaddrinfo
配置好主机参数addrinfo后使用uv_getaddrinfo即可

调用uv_interface_addresses获得系统的网络信息

未完待续。

来源:http://luohaha.github.io/Chinese-uvbook/source/introduction.html

使用gyp

GYP(Generate You Project),生成IDE项目的工具,使用Python脚本写成,配置文件为JSON格式。

使用gyp需要两个环境,python和gyp。gyp可以直接在这里下载

git clone https://chromium.googlesource.com/external/gyp

一般下载到build/gyp

使用python将我们的gyp文件加载并运行起来

args中可以添加工程的配置文件,大概格式如下:

target_name:工程名

type: 工程类型

dependencies: 依赖文件夹

sources: 源文件

conditions:条件判断

msvs-settings:msvs额外设置

 

JS-深拷贝

在JS中使用变量,使用=号拷贝,如

obj1 = obj2

是浅拷贝,即改变obj1内容的时候也会改变obj2.

有时候我们是不希望看到这种情况的,JS使用深拷贝有很多方法,介绍一个简单好用的

这种用法会破坏obj2的构造类型,但一般情况是足够了。

Linux入门-使用脚本

在linux上开发,经常有一些重复性劳动,建议写成脚本,省时省力还不出错。

1.新建一个文件

vi filename

如vi test.sh

2.编辑内容,linux上sh的形式比较一致

#!/bin/sh
#comments

然后跟上自己的命令就可以了,比如

mkdir tmp

cd tmp

3.最后chmod +x test.sh,可执行,就可以执行了

4.执行完毕后,你会发现确实创建了tmp,但当前目录没有变。

这是因为脚本执行时会创建一个子环境,执行完毕后回到当前环境,如果你想直接改变当前环境,使用source 来执行脚本就可以了

source test.sh

就可以看到目录切到tmp下。

Linux服务器-windows远程开发

最近项目需要在Linux环境下,本人的本是windows,怎么办么?

答:申请一台服务器,linux环境,用ssh工具就可以开发了

不过服务器上只能用vim开发,开发起来惨不忍睹,怎么办?

答:远程开发

远程开发的原理很简单,就是把服务器上的文件夹映射到windows上,就可以像windows本地开发一样了。

首先在Linux服务器上安装samba,装好后给自己配置一个samba用户,具体方法请自行百度,参考链接:http://blog.csdn.net/i_chips/article/details/19191957。

window端打开计算机,有一个映射网络驱动器选项

samba_3

打开后有两个选项

samba_4

第一个是盘符,默认就行,红框所选的地方 写上要映射的服务器文件夹地址。

填好之前在samba上配置的账号/密码,就可以用了。

使用YUIdoc

最近遇到任务,需要对外提供接口。发现最困难的事是写文档,因为代码经常在修改,每天更新word很困难。然后就发现了文档神器YUI doc,以及神器的剑鞘smartdoc:http://www.cnblogs.com/zhh8077/p/4010991.html。

简单介绍一下使用方法和遇到的坑。

YUI doc可以看成一种标准,主要看这里http://www.cnblogs.com/zhh8077/p/4011769.html或者YUI doc的官方文档。

module写法

class写法

method常用写法

其中 param.xx是二级参数的写法。

event与method一样

常量

smartdoc的使用就比较简单了,参考其主页文档。

这里主要想说的是 使用过程中遇到的一些坑。

1.生成的method event等等按照字母顺序排列,而不是按照我们文档中的顺序排列。

.YUIDoc生成的API文档目录不按源文件注释顺序

YUIDoc默认将所有的class、method、properties、events等按字母进行排序。

而且这个是在生成文档时进行排序的,所以如果除去按字母进行排序这种默认行为。

就必须修改YUIDoc的工具文件。修改C:\Users\Administrator\AppData\Roaming\npm\node_modules\yuidocjs\lib 下的 builder.js 文件

第1313-1316行,就是这几句罪魁祸首,注释掉后就可以按源文件注释顺序,当然你也可以自己弄其他排序方法。

方法源自:http://www.cnblogs.com/lovesong/p/3341453.html

2.event的example不显示。使用smartdoc生成文档后,其他地方都挺好,但event的example就是显示不出来。chrome上面,直接F12,看document,看到example部分,display:none。method增加了一个active的class,display:block。很简单,看看这个css是在哪里写的。

C:\Users\用户名\AppData\Roaming\npm\node_modules\smartdoc\theme-smart\assets\css

路径下的main.css。改一下其中的example的display就可以了。

修改整个页面的布局也是修改这里。这里就是我们使用的主题,自己可以改,也可以搞一套。

 

am指令带参数启动app

使用am指令启动app

带参数启动app有两种方法

1. 传入一个字符串

app内取数据

2. 传入键值对

app内通过取数据  ei表示传入的是int es表示传入的是String

3. 关闭Activity

参考链接