首页 文章 精选 留言 我的

精选列表

搜索[监督学习],共10000篇文章
优秀的个人博客,低调大师

Android学习笔记--Activity初步

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 1.Activity的主要作用(UI)应用程序组件 创建一个activity类 创建Activity要点 a.一个activity就是一个类,并且这个类要继承activity b.需要从写onCreate方法(程序运行首先调用) c.在配置文件中注册每一个activity d.要为activity中添加必要的控件 e.对应布局文件一个布局文件对应一个activity 得到控件例findViewById(R.id.MyButton); 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360579,如需转载请自行联系原作者

优秀的个人博客,低调大师

2、权限、变量、for 学习笔记

ls 显示目录内容,不包含以点开头的文件 ls -a 显示目录内容,包含以点开头的文件 ls -l 长格式显示目录内容 ls -d 显示目录自身的信息,通常与-l同时使用 ls -r 逆序显示目录内容 ls -R 递归显示目录内容 ls -h 以易读的方式显示文件大小,通常与-l同时使用 ls -i 显示inode信息 tree 树状形式显示目录内容 alias 显示当前shell中定义的所有别名 alias 别名='原始命令' 定义别名 unalias 别名 删除命令别名 file FILE... 查看文件内容格式 cat -E FILE 显示行结束符 cat -v FILE 显示非打印字符 cat -e FILE 相当于-vE cat -n FILE 显示时给行按顺序编号 cat -s FILE 多个连续的空白行显示为一个空白行 head -# 显示文件顶部#行的内容 tail -# 显示文件尾部#行的内容 tail -#f 动态显示文件尾部#行的内容 echo命令的用法: echo -e "\033[##;##m string \033[0m" 第一个#: 3表示前景色,4表示背景色 第二个#:颜色,0-7 0 黑色 1 红色 2 绿色 3 黄色 4 蓝色 5 紫色 6 天蓝 7 白色 echo -e "\033[31;42;5m LINUX \033[0m" 效果:绿底红字闪烁 通配符: * 匹配任意长度的任意字符 ? 匹配任意单个字符 [] 匹配指定字符范围内的任意单个字符 [^] 匹配指定字符范围外的任意单个字符 [:upper:]] 所有大写字母 [:lower:]] 所有小写字母 [:alpha:]] 所有字母 [:digit:]] 0-9 [:alnum:]] 0-9及所有字母 [:space:]] 所有空白字符 [:punct:]] 所有标点符号 练习:复制/var目录下所有以l开头,以一个小写字母结尾,且中间出现一位数字的文件或目录至/tmp下 cp -r /var/1*[0-9]*[a-z] /tmp 练习:如果符合条件是目录,也要复制; 1、复制/etc目录下以p开头,中间跟了任意字符,并以d结尾的文件至/tmp目录中; 2、复制/etc/目录下以p开头,中间跟了4个任意字符,并以d结尾的文件至/tmp/a目录中;如果a不存在,先创建出来; 3、复制/etc/目录下以任意一位数字开头,并以非数字结尾的文件至/tmp/b目录中; 4、复制/etc/目录下以非字母开头,后面跟了一个字母及其它任何长度字符的文件至/tmp/c目录中; 1、cp -r /etc/p*d /tmp 2、cp -r /etc/p????d /tmp/a 3、cp -r /etc/[0-9]*[^0-9] /tmp/b 4、cp -r /etc/[^[:alpha:]][[:alpha:]]* /tmp/c cp命令的长用选项: -r:递归 -d: 当源为链接文件时,复制链接文件本身而非指向的源文件 -p: 保持原有属性 mv: 移动文件,或重命名 rm: 移除文件 删除非空目录:# rm -rf stat FILE 显示文件或文件系统信息,包含(access、modify、change时间) touch FILE 创建空文件或修改文件时间信息 -c: 不创建空文件 -a: 仅修改访问时间 -m: 仅修改修改时间 -t STAMP: [CC]YYMMDDhhmm.ss 修改当前时间 /etc/passwd: 用户名:x:UID:基本组ID:comment信息:HOME:默认shell useradd: adduser -u UID:指定UID -g GID: 指定GID,即指定用户的基本组,但GID要事先存在 -G GID:指定用户的额外组,组要事先存在; -c "Comment": -d /path/to/somewhre: -s /path/to/shell: 指定默认shell,应该指定使用/etc/shells文件中出现的shell; -m: 创建用户时,强制给用户创建家目录; -M: 创建用户,但不创建家目录; -r: 创建系统用户 id: 1-499 不会为用户创建家目录 默认shell为/sbin/nologin groupadd GrpName -g GID: 创建组并为其指定GID 用户类别: 管理员:0 普通用户:1-65535 系统用户:1-499 登录用户:500+ 用户组: 管理员组 普通组 以用户为视角,组可为两类: 基本组: 显示在/etc/passwd中GID字段组,为用户的基本组; 额外组,附加组: /etc/group userdel: 删除用户, 默认会保留家目录 格式:userdel UserName -r: 一并删除家目录 设定用户密码: passwd 普通用户:passwd 管理员: 改自己密码:passwd 改其它用户密码:passwd UserName /etc/shadow文件的格式: UserName:加密的密码:最近一次密码修改时间:最短使用期限:最长使用期限:警告区间:非活动区间:帐号的过期期限:预留段 passwd -l UserName 锁用户 passwd -u UserName 解锁 设定组密码:gpasswd GroupName usermod: -u UID: -g GID: -G GID: 默认会覆盖原有的附加组;如果是添加,则同时使用-a选项; -c String: -d /path/to/New_Home: 默认不会迁移用户的家目录;如果要迁移,则同时使用-m -s SHELL: -l New_login_name: -L: 锁定用户帐号 -U: 解锁 如何修改组属性定义: groupmod: -g GID -n New_Group_Name: UserName:加密的密码:最近一次密码修改时间:最短使用期限:最长使用期限:警告区间:非活动区间:帐号的过期期限:预留段 修改帐号日期属性:chage -m 修改最短使用期限。为零时代表任何时候都可以更改密码 -M 修改最长使用期限。密码保持有效的最大天数 -W 修改警告区间。用户密码到期前,提前收到警告信息的天数 -I 修改非活动区间或停滞日期。如果一个密码已过期这些天,那么此帐号将不可用 -E 修改帐号的过期期限。过了这天,此帐号将不可用 查看用户相关信息id: id UserName -u: 显示UID,跟-n一起使用则显示用户名 -g: 显示基本组ID,跟-n一起使用则显示基本组名 -G: 显示所有组ID,跟-n一起使用则显示所有组名 su -l UserName 切换用户,且切换到该用户的家目录 练习: 1、创建一个用户mandriva,其ID号为2002,基本组为distro(组ID为3003),附加组为linux; # groupadd linux # groupadd -g 3003 distro # useradd -u 2002 -g distro -G linux mandriva 2、创建一个用户fedora,其全名为Fedora Community,默认shell为tcsh; # useradd -c "Fedora Community" -s /bin/tcsh fedora 3、修改mandriva的ID号为4004,基本组为linux,附加组为distro和fedora; # usermod -u 4004 -g linux -G distro,fedora mandriva 4、给fedora加密码,并设定其密码最短使用期限为2天,最长为50天; # passwd fedora # chage -m 2 -M 50 fedora 5、将mandriva的默认shell改为/bin/bash; # chsh -s /bin/bash mandriva Linux文件类型: 普通文件 - 目录 d 链接文件 l 字符设备 c 块设备 b 命名管道 p 套接字文件 s 权限:read, write, execute 用户不拥有某位权限,则使用 - 占位; 文件: r: 可以使用内容查看类的命令来显示其相关内容; w: 可以使用编辑器修改其内容; x: 可以将其发起一个进程; 目录: r: 可以使用ls命令查看目录内容的文件信息; w: 可以创建、删除文件; x: 可以使用ls -l命令查看目录内容的文件信息,并且可用cd命令切换此目录为工作目录; chmod命令: 操作三类用户的权限:使用8进制形式 chmod [-R] OCTAL-MODE file... -R可以递归修改目录下文件的权限 操作指定类别用户的权限:使用u,g,o,a来赋权,基于=或+/-来进行 u: 属主 g: 属组 o: 其它 a: 所有 =:操作指定类别用户的权限;u=, ug=, u=,g= +/-: 操作指定类别用户的单个权限: u-x, g+r, o-x, +x 参照其它文件的权限为当文件赋权 --reference=要参照的文件 要修改权限的文件 umask 创建文件:666-umask 文件默认决不允许出现执行权限,如何具有执行权限,则权限值加1; 创建目录:777-umask root用户的umask为022;用户名和基本组组名一致umask为002,否则umask为022; 修改文件的属主或属组:chown, chgrp -R: 递归 --reference= chown [option] UserName[{:|.}GroupName] file... 权限应用模型: 进程的属主,是否与文件的属主相同;如果相同,进程则以文件属主的权限来访问文件;否则 进程的属主所属的组,是否其中之一与文件的属组相同;如果相同,进程则以文件属组的权限来访问文件;否则, 进程则以文件的其它用户的权限来访问文件; 练习: 1、新建一个用户openstack,但不给其创建家目录;创建完成后使用su命令切换至此用户,查看其命令提示符及PATH和HOME两个环境变量的值; # useradd -M openstack # su - openstack # echo $PATH $HOME 2、复制/etc/skel目录为/home/openstack; # cp -r /etc/skel /home/openstack 3、改变/home/openstack及其内部文件的属主属组均为openstack; # chown -R openstack.openstack /home/openstack 4、/home/openstack及其内部的文件,属组和其它用户没有任何访问权限; # chmod -R go= /home/openstack # su - openstack # echo $PATH $HOME 练习: 完成以下任务: (1)新建系统组mysql;新建系统用户mysql,属于mysql组,要求其没有家目录且shell为/sbin/nologin; # groupadd -r mysql # useradd -r -s /sbin/nologin -g mysql mysql (2)新建GID为600的组magedu;新建用户gentoo,要求其家目录为/users/gentoo,密码同用户名; # groupadd -g 600 magedu # mkdir /users # useradd -d /users/gentoo gentoo # passwd gentoo (3)新建用户centos,其家目录为/users/centos,密码同用户名; # useradd -d /users/centos centos # passwd centos (4)新建用户www,其家目录为/users/www;删除www用户,但保留其家目录; # useradd -d /users/www www # userdel www (5)用户gentoo和centos均以magedu为其附加组; # usermod -a -G magedu gentoo # usermod -a -G magedu centos bash特性之六:bash的快捷键 Ctrl+a: 跳至命令行首 Ctrl+e: 跳至命令行尾 Ctrl+u: 删除命令行首至当前光标所在处的内容 Ctrl+k: 删除当前光标所有处至命令行尾的内容 Ctrl+l: 清屏,相当于clear命令 Ctrl+c: 取消或终止; Ctrl+z: 将当前命令送至后台,fg调回前台 ELF: #!/bin/bash 程序=指令+数据 变量: 弱类型语言: 1、不强制区分变量的类型,无论存储何种数据,均以字符格式进行; 2、无须事先声明;用到时,直接使用,直接赋值; bash: 动态编程语言,是弱类型语言; bash的特性之九:bash中的变量 变量的类型: 本地变量:只对当前shell进程有效,对其子shell以及其它shell都无效; 定义变量: [set]Var_Name="Value" 引用变量: ${Var_Name} 撤销变量: unset Var_Name 局部变量:仅对局部代码生效 local Var_Name="Value" 环境变量:对当前shell进程及其子shell都有效; export Var_Name="Value" 或 Var_Name="Value" export Var_Name 位置变量: $1, ..., $n ./first.sh 2 8 特殊变量: $0: 脚本名称自身 $?: 上一条命令的执行状态; 状态用数字来表示:0-255; 0: 成功 1-255: 失败 $$ $! $# 位置参数的个数 $* 所有的位置参数 变量的命名要求: 只能使用数字、字母和下划线组成; 不能以数字开头; 不能使用程序中的关键字; 见名知义;totalWeight set 环境变量:用来bash的工作特性,用于保存当前会话的属性信息; 显示所有环境变量:export, env, printenv 定义:export Var_Name="Value" PATH, PS1 bash的配置文件:持久保存用户配置 profile类:为交互式登录的用户提供配置 /etc/profile:全局 /etc/profile.d/*.sh:全局 ~/.bash_profile:个人配置,仅对当前用户有效 功能: 设定环境变量 运行命令或脚本 bashrc类:非交互工登录用户提供配置 /etc/bashrc: 全局 ~/.bashrc: 个人配置 功用: 设定本地变量 定义命令别名 登录类型: 交互式登录: 直接通过终端输入用户信息登录系统; su - UserName或su -l UserName; 非交互式登录: su UserName 图形界面的终端 执行脚本 新增配置的生效方式: 通知shell重读配置文件的命令: source (.) . FILE 重新登录 交互式登录用户: /etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc 非交互式登录用户: ~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh bash脚本:面向过程的编程中 顺序执行:默认法则,逐条执行各语句 选择执行:分支,条件判断,符合条件的分支予以执行; 循环执行:将同一段代码反复执行有限次,所以,循环必须有退出条件,否则将陷入死循环; for循环: for var_Name in 列表; do 语句1 语句2 ... done 语法错误检测: # bash -n 脚本文件 列表的生成方法: 生成数字序列:{start..end}、seq [start] [step] end 练习:写一个脚本,列出1-10的奇数 #!/bin/bash for num in `seq 1 2 10`; do echo $num done 练习:写一个脚本,用file命令显示/var/log目录下每个文件的内容类型; 提示:列表生成的方法为/var/log/* #!/bin/bash # dirName=/var/log for fileName in $dirName/*; do file $fileName done 练习:写一个脚本, 1、创建/tmp/scripttest目录,用变量保存目录名; 2、在目录里创建测试文件tfile1-tfile20; 3、创建用户testuser1和testuser2; 4、将tfile1-tfile10的属主和属组改为testuser1; 5、将tfile11-tfile20的属主和属组改为testuser2; #!/bin/bash dirName=/tmp/scripttest mkdir $dirName for fileNo in {1..20}; do touch $dirName/tfile$fileNo echo "Create $dirName/tfile$fileNo finished" done useradd testuser1 useradd testuser2 for fileNo in {1..10}; do chown testuser1:testuser1 $dirName/tfile$fileNo done for fileNo in {11..20}; do chown testuser2:testuser2 $dirName/tfile$fileNo done 文本处理类的命令:wc, word count wc [option] [file]... -l: 统计行数 -c: 统计字节数 -w;统计单词数 tr: 转换字符或删除字符 tr '集合1' '集合2' 将集合1替换为集合2 tr -d '字符集合' 删除字符集合 cut -d字符 -f# 操作对象 -d字符:指定分隔符 -f#: 指定要显示字段 单个数字:一个字段 逗号分隔的多个数字:指定多个离散字段 -:连续字段,如3-5; sort: 默认按字符进行比较 sort [option] file... -f: 忽略字符大小写; -n: 比较数值大小; -u: 重复的行,只显示一次; -t: 指定分隔符 -k: 指定分隔后进行比较字段 uniq: 移除重复的行 -c:显示每行重复的次数 -d:仅显示重复过的行 -u: 仅显示不曾重复的行 练习: 1、统计/bin、/usr/bin、/sbin和/usr/sbin等各目录中的文件个数; # ls /bin | wc -l 2、显示当前系统上所有用户的shell,要求,每种shell只显示一次; # cut -d: -f7 /etc/passwd | sort -u 3、取出/etc/passwd文件的第7行; # head -7 /etc/passwd | tail -1 4、显示第3题中取出的第7行的用户名; # head -7 /etc/passwd | tail -1 | cut -d: -f1 # head -7 /etc/passwd | tail -1 | cut -d: -f1 | tr 'a-z' 'A-Z' 5、统计/etc目录下以P或p开头的文件个数; # ls -d /etc/[Pp]* | wc -l 练习:写一个脚本,用for循环实现 显示/etc/init.d/functions、/etc/rc.d/rc.sysinit和/etc/fstab各有多少行; #!/bin/bash for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do wc -l $fileName done #!/bin/bash for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do lineCount=`wc -l $fileName | cut -d' ' -f1` echo "$fileName: $lineCount lines." done #!/bin/bash for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do echo "$fileName: `wc -l $fileName | cut -d' ' -f1` lines." done 练习:写一个脚本 将上一题中三个文件的复制到/tmp目录中; 用for循环实现,分别将每个文件的最近一次的修改时间改为2011年9月15号13点27分; #!/bin/bash for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do cp $fileName /tmp baseName=`basename $fileName` touch -m -t 201109151327 /tmp/$baseName done 练习:写一个脚本 显示/etc/passwd中第3、7和11个用户的用户名和ID号; #!/bin/bash # for lineNo in 3 7 11; do userInfo=`head -n $lineNo /etc/passwd | tail -1 | cut -d: -f1,3` echo -e "User: `echo $userInfo | cut -d: -f1`\nUid: `echo $userInfo |cut -d: -f2`" done for:通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环; 总结:生成列表的方式 1、直接给出列表; 2、使用文件名通配的机制生成列表 3、可以使用{}或seq命令生成数字序列 1, $lineCount `seq 1 $lineCount` {1..$lineCount} 4、使用命令生成 本文转自开源殿堂 51CTO博客,原文链接:http://blog.51cto.com/kaiyuandiantang/1934514,如需转载请自行联系原作者

优秀的个人博客,低调大师

Web Service学习笔记(1)

Web Service的宗旨是创建不需要用户界面就能与其他应用程序交互的Web应用程序。 举例说明它的优点,假如你正在为一家股票投资公司创建网站,你并不需要把不同证劵交易所得数据库与自己的后台数据库进行整合,因为你的应用程序可以使用Web Service,并使用XML格式交换数据。 Web Service是松耦合的,它与服务器端和客户端使用的操作系统、编程语言都无关。假如你既拥有客户端又有服务器端的访问和管理权,这种情况更适合用.NET的Remoting技术,而不是Web service。 创建Web Service必须保证的是,服务器端和客户端都要支持HTTP、SOAP(简单对象访问协议)和XML等行业标准协议。 Web Service是如何工作的 Web Service允许两个程序之间交换XML文档。在这个架构的顶层,微软实现了一个远程过程调用(Remote Procedure Call,PRC)模型。 Web Service架构包括以下特性: 1。WebServcie的服务器端和客户端应用程序都能够连接到互联网。 2。用于进行通信的数据格式必须遵守相同的开放标准,并且在大多数情况下,这个标准几乎总是SOAP。 3。客户端和服务器端的系统是松耦合的。即Web Service不关心客户端和服务器端所使用的操作系统、对象模型或者编程语言。只要Web Service和使用Web Service的应用程序都能够发送和接收遵守适当协议标准的消息即可。 下图为Web Service流程的逻辑架构 如图所示,一个Web Service使用着会向Web Service发出一个调用请求。使用者会认为它通过Internet直接和Web Service进行交流,当然这实际上是个幻象。实际上,真正的调用由代理类完成。代理类对于Web Service使用者来说是一个本地类。代理会处理所有的负责的复杂架构,包括通过Internet发送请求道服务器、从web Service取回结果并呈现给Web Service使用者。 由于代理类在之前已在消费程序中注册,所有一切工作才可以顺利进行。注册有开发消费程序的程序员完成。 开发Web Service 开发Web Service的流程与开发网页的流程近乎一致: 1。所有构成网页和服务的源文件都是文本文件,它们可以使用任何文本编辑器创建和修改。而类文件可以在控制台命令行中通过命令工具进行编译。 2。可以在vs2005及以上版本中创建网页和Web Service 3。网页和Web Service既可以使用代码隐藏模型,也可以使用内联编码(inline coding)模型。Web Service中不需要使用代码隐藏技术,因为Web Service并不包括任何可视化内容。 4。网页和Web Service都充分利用了CLR和.NET Framework。 .aspx文件用于定义网页,而.asmx文件用于定Web Service,我们可以吧Web Service想象成类,类中的一些方法通过Internet被暴露给客户端。 代理 客户端应用程序如果使用Web Service,必须先创建一个代理。代理是要调用的真正代码的替身,它负责在机器边界引导调用。在代理在客户端应用程序中注册后,客户端应用程序调用方法就如调用本地对象一样。代理接受该调用,并以适当格式封装调用,然后以SOAP请求发送调用到服务器。当服务器返回SOAP包给客户端后,代理会对包进行解密,并且如同从本地对象的方法返回数据一样将其返回给客户端应用程序。如下图所示: 协议与标准(HTTP、XML、SOAP) HTTP:TCP/IP协议的最上层是超文本传输协议(HTTP)。它是用于在网络之间使用服务器和浏览器实现通讯,主要包括在服务器和浏览器建立连接,并将HTML传输到客户端浏览器。当客户端向服务器发送HTTP请求后,服务器就开始处理请求。通常,会返回HTML页面,然后通过浏览器呈现。然而对Web Service而言,服务器返回的是SOAP消息,消息中包含了被调用的Web Service方法的返回数据。 HTTP请求从请求的浏览器出传递名称和值到服务器,这种请求包括GET和POST两种。 GET请求中,名称和值会被附加到url上,数据是未加密的。当所有需要传递的数据可以使用名称和值成对表示,而且只需要传递少量字段,字段长度较短时,比较适合GET请求。另外,如果不需考虑安全问题时,也可以使用GET。 POST请求中,配对的名称和值是作为请求消息的一部分发送的。当有大量字段或者参数很长时,适合使用POST请求。从安全方面看,POST比GET更安全,因为POST请求可以被加密。和GET请求一样,POST请求无法传递复杂的数据类型(如类、结构体和DataSet)。 XML:是有W3C公布的开放标准的一种描述数据的方法。 XML和HTML十分类似。不同的是HTML使用的是预定义元素,这些元素规定了HTML在浏览器中如何显示,而XML的元素则是由开放人员自己定义的,所以几乎所有的数据都可以表示。制定XML的目的是为了使其成为一种平台无关、语言无关的标准。 XML架构(Schema)是用于定义元素已经XML文档中或者许多XML之间元素与元素之间关联的文件。在架构中将指定元素名称和内容类型。HTML与XML的显著差别:大多数HTML读取器有很好的容错能力,而XML读取器则完全不同,所以XML文件的格式必须正确。另外,XML元素都是小写的。 SOAP:(simple object access protocol,简单对象访问协议)是一种用于控制数据交换的XML语法。它是简单的、轻量级的信息交换协议。SOAP消息有消息内容和一个或多个头模块组成,并且封装在SOAP envelope中。 SOAP使用XML语法来格式化内容。在设计上,SOAP尽可能简单并且提供最小化的功能。 SOAP不需HTTP的GET和POST,它不受“名称/值”对的限制,我们可以使用它来发送复杂的对象,包括DataSet、类和其他对象。 SOAP的缺点:SOAP消息十分冗长,因此如果存在带宽或者传输性能的问题,建议使用POST或GET。 本文转自xshf12345 51CTO博客,原文链接:,http://blog.51cto.com/alexis/573704 如需转载请自行联系原作者

优秀的个人博客,低调大师

有关Android线程的学习

1. Android进程 在了解Android线程之前得先了解一下Android的进程。当一个程序第一次启动的时候,Android会启动一个LINUX进程和一个主线程。默认的情况下,所有该程序的组件都将在该进程和线程中运行。同时,Android会为每个应用程序分配一个单独的LINUX用户。Android会尽量保留一个正在运行进程,只在内存资源出现不足时,Android会尝试停止一些进程从而释放足够的资源给其他新的进程使用, 也能保证用户正在访问的当前进程有足够的资源去及时地响应用户的事件。Android会根据进程中运行的组件类别以及组件的状态来判断该进程的重要性,Android会首先停止那些不重要的进程。按照重要性从高到低一共有五个级别: 前台进程 前台进程是用户当前正在使用的进程。只有一些前台进程可以在任何时候都存在。他们是最后一个被结束的,当内存低到根本连他们都不能运行的时候。一般来说, 在这种情况下,设备会进行内存调度,中止一些前台进程来保持对用户交互的响应。 可见进程 可见进程不包含前台的组件但是会在屏幕上显示一个可见的进程是的重要程度很高,除非前台进程需要获取它的资源,不然不会被中止。 服务进程 运行着一个通过startService() 方法启动的service,这个service不属于上面提到的2种更高重要性的。service所在的进程虽然对用户不是直接可见的,但是他们执行了用户非常关注的任务(比如播放mp3,从网络下载数据)。只要前台进程和可见进程有足够的内存,系统不会回收他们。 后台进程 运行着一个对用户不可见的activity(调用过 onStop() 方法).这些进程对用户体验没有直接的影响,可以在服务进程、可见进程、前台进 程需要内存的时候回收。通常,系统中会有很多不可见进程在运行,他们被保存在LRU (least recently used) 列表中,以便内存不足的时候被第一时间回收。如果一个activity正 确的执行了它的生命周期,关闭这个进程对于用户体验没有太大的影响。 空进程 未运行任何程序组件。运行这些进程的唯一原因是作为一个缓存,缩短下次程序需要重新使用的启动时间。系统经常中止这些进程,这样可以调节程序缓存和系统缓存的平衡。 Android 对进程的重要性评级的时候,选取它最高的级别。另外,当被另外的一个进程依赖的时候,某个进程的级别可能会增高。一个为其他进程服务的进程永远不会比被服务的进程重要级低。因为服务进程比后台activity进程重要级高,因此一个要进行耗时工作的activity最好启动一个service来做这个工作,而不是开启一个子进程――特别是这个操作需要的时间比activity存在的时间还要长的时候。例如,在后台播放音乐,向网上上传摄像头拍到的图片,使用service可以使进程最少获取到“服务进程”级别的重要级,而不用考虑activity目前是什么状态。broadcast receivers做费时的工作的时候,也应该启用一个服务而不是开一个线程。 2. 单线程模型 当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。 2.1 子线程更新UI Android的UI是单线程(Single-threaded)的。为了避免拖住GUI,一些较费时的对象应该交给独立的线程去执行。如果幕后的线程来执行UI对象,Android就会发出错误讯息CalledFromWrongThreadException。以后遇到这样的异常抛出时就要知道怎么回事了! 2.2 Message Queue 在单线程模型下,为了解决类似的问题,Android设计了一个Message Queue(消息队列), 线程间可以通过该Message Queue并结合Handler和Looper组件进行信息交换。下面将对它们进行分别介绍: 1. Message Message消息,理解为线程间交流的信息,处理数据后台线程需要更新UI,则发送Message内含一些数据给UI线程。 2. Handler Handler处理者,是Message的主要处理者,负责Message的发送,Message内容的执行处理。后台线程就是通过传进来的Handler对象引用来 sendMessage(Message)。而使用Handler,需要implement 该类的 handleMessage(Message)方法,它是处理这些Message的操作内容,例如Update UI。通常需要子类化Handler来实现handleMessage方法。 3. Message Queue Message Queue消息队列,用来存放通过Handler发布的消息,按照先进先出执行。 每个message queue都会有一个对应的Handler。Handler会向message queue通过两种方法发送消息:sendMessage或post。这两种消息都会插在message queue队尾并按先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过sendMessage发送的是一个message对象,会被Handler的handleMessage()函数处理;而通过post方法发送的是一个runnable对象,则会自己执行。 4. Looper Looper是每条线程里的Message Queue的管家。Android没有Global的Message Queue,而Android会自动替主线程(UI线程)建立Message Queue,但在子线程里并没有建立Message Queue。所以调用Looper.getMainLooper()得到的主线程的Looper不为NULL,但调用Looper.myLooper()得到当前线程的Looper就有可能为NULL。 对于子线程使用Looper,API Doc提供了正确的使用方法: classLooperThreadextendsThread{ publicHandlermHandler; publicvoidrun(){ Looper.prepare();//创建本线程的Looper并创建一个MessageQueue mHandler=newHandler(){ publicvoidhandleMessage(Messagemsg){ //processincomingmessageshere } }; Looper.loop();//开始运行Looper,监听MessageQueue } } 这个Message机制的大概流程: 1. 在Looper.loop()方法运行开始后,循环地按照接收顺序取出Message Queue里面的非NULL的Message。 2. 一开始Message Queue里面的Message都是NULL的。当Handler.sendMessage(Message)到Message Queue,该函数里面设置了那个Message对象的target属性是当前的Handler对象。随后Looper取出了那个Message,则调用该Message的target指向的Hander的dispatchMessage函数对Message进行处理。 在dispatchMessage方法里,如何处理Message则由用户指定,三个判断,优先级从高到低: 1) Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作; 2) Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理; 3) 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。 由此可见,我们实现的handleMessage方法是优先级最低的! 3. Handler处理完该Message (update UI) 后,Looper则设置该Message为NULL,以便回收! 在网上有很多文章讲述主线程和其他子线程如何交互,传送信息,最终谁来执行处理信息之类的,个人理解是最简单的方法——判断Handler对象里面的Looper对象是属于哪条线程的,则由该线程来执行! 1. 当Handler对象的构造函数的参数为空,则为当前所在线程的Looper; 2.Looper.getMainLooper()得到的是主线程的Looper对象,Looper.myLooper()得到的是当前线程的Looper对象。 现在来看一个例子,模拟从网络获取数据,加载到ListView的过程: publicclassListProgressDemoextendsListActivity{ @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.listprogress); ((Button)findViewById(R.id.load_Handler)).setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewview){ data=null; data=newArrayList<String>(); adapter=null; showDialog(PROGRESS_DIALOG); newProgressThread(handler,data).start(); } }); } @Override protectedDialogonCreateDialog(intid){ switch(id){ casePROGRESS_DIALOG: returnProgressDialog.show(this,"", "Loading.Pleasewait...",true); default:returnnull; } } privateclassProgressThreadextendsThread{ privateHandlerhandler; privateArrayList<String>data; publicProgressThread(Handlerhandler,ArrayList<String>data){ this.handler=handler; this.data=data; } @Override publicvoidrun(){ for(inti=0;i<8;i++){ data.add("ListItem");//后台数据处理 try{ Thread.sleep(100); }catch(InterruptedExceptione){ Messagemsg=handler.obtainMessage(); Bundleb=newBundle(); b.putInt("state",STATE_ERROR); msg.setData(b); handler.sendMessage(msg); } } Messagemsg=handler.obtainMessage(); Bundleb=newBundle(); b.putInt("state",STATE_FINISH); msg.setData(b); handler.sendMessage(msg); } } //此处甚至可以不需要设置Looper,因为Handler默认就使用当前线程的Looper privatefinalHandlerhandler=newHandler(Looper.getMainLooper()){ publicvoidhandleMessage(Messagemsg){// 处理Message,更新ListView intstate=msg.getData().getInt("state"); switch(state){ caseSTATE_FINISH: dismissDialog(PROGRESS_DIALOG); Toast.makeText(getApplicationContext(), "加载完成!", Toast.LENGTH_LONG) .show(); adapter=newArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, data); setListAdapter(adapter); break; caseSTATE_ERROR: dismissDialog(PROGRESS_DIALOG); Toast.makeText(getApplicationContext(), "处理过程发生错误!", Toast.LENGTH_LONG) .show(); adapter=newArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, data); setListAdapter(adapter); break; default: } } }; privateArrayAdapter<String>adapter; privateArrayList<String>data; privatestaticfinalintPROGRESS_DIALOG=1; privatestaticfinalintSTATE_FINISH=1; privatestaticfinalintSTATE_ERROR=-1; } 这个例子,我自己写完后觉得还是有点乱,要稍微整理才能看明白线程间交互的过程以及数据的前后变化。随后了解到AsyncTask类,相应修改后就很容易明白了! 2.3 AsyncTask AsyncTask版: ((Button)findViewById(R.id.load_AsyncTask)).setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewview){ data=null; data=newArrayList<String>(); adapter=null; //显示ProgressDialog放到AsyncTask.onPreExecute()里 //showDialog(PROGRESS_DIALOG); newProgressTask().execute(data); } }); privateclassProgressTaskextendsAsyncTask<ArrayList<String>,Void,Integer>{ /*该方法将在执行实际的后台操作前被UIthread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。*/ @Override protectedvoidonPreExecute(){ //先显示ProgressDialog showDialog(PROGRESS_DIALOG); } /*执行那些很耗时的后台计算工作。可以调用publishProgress方法来更新实时的任务进度。*/ @Override protectedIntegerdoInBackground(ArrayList<String>...datas){ ArrayList<String>data=datas[0]; for(inti=0;i<8;i++){ data.add("ListItem"); } returnSTATE_FINISH; } /*在doInBackground执行完成后,onPostExecute方法将被UIthread调用, *后台的计算结果将通过该方法传递到UIthread. */ @Override protectedvoidonPostExecute(Integerresult){ intstate=result.intValue(); switch(state){ caseSTATE_FINISH: dismissDialog(PROGRESS_DIALOG); Toast.makeText(getApplicationContext(), "加载完成!", Toast.LENGTH_LONG) .show(); adapter=newArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, data); setListAdapter(adapter); break; caseSTATE_ERROR: dismissDialog(PROGRESS_DIALOG); Toast.makeText(getApplicationContext(), "处理过程发生错误!", Toast.LENGTH_LONG) .show(); adapter=newArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, data); setListAdapter(adapter); break; default: } } Android另外提供了一个工具类:AsyncTask。它使得UI thread的使用变得异常简单。它使创建需要与用户界面交互的长时间运行的任务变得更简单,不需要借助线程和Handler即可实现。 1) 子类化AsyncTask 2) 实现AsyncTask中定义的下面一个或几个方法 onPreExecute() 开始执行前的准备工作; doInBackground(Params...) 开始执行后台处理,可以调用publishProgress方法来更新实时的任务进度; onProgressUpdate(Progress...) 在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。 onPostExecute(Result) 执行完成后的操作,传送结果给UI 线程。 这4个方法都不能手动调用。而且除了doInBackground(Params...)方法,其余3个方法都是被UI线程所调用的,所以要求: 1) AsyncTask的实例必须在UI thread中创建; 2) AsyncTask.execute方法必须在UI thread中调用; 同时要注意:该task只能被执行一次,否则多次调用时将会出现异常。而且是不能手动停止的,这一点要注意,看是否符合你的需求! 在使用过程中,发现AsyncTask的构造函数的参数设置需要看明白: AsyncTask<Params, Progress, Result> Params对应doInBackground(Params...)的参数类型。而new AsyncTask().execute(Params... params),就是传进来的Params数据,你可以execute(data)来传送一个数据,或者execute(data1, data2, data3)这样多个数据。 Progress对应onProgressUpdate(Progress...)的参数类型; Result对应onPostExecute(Result)的参数类型。 当以上的参数类型都不需要指明某个时,则使用Void,注意不是void。不明白的可以参考上面的例子,或者API Doc里面的例子。 ---------------- 本文的相当内容摘录于《 浅析Android线程模型一 --- 转》,但对于Message机制的流程理解则在参考《 android中Message机制的灵活应用》后修改了! 本文转自 Icansoft 51CTO博客,原文链接: http://blog.51cto.com/android/343823

优秀的个人博客,低调大师

Android学习笔记--创建Dialog

创建Dialog 1.分类 (1)AlertDialog.它能够管理0个`1个`2个`3个按钮和一个包含radio或者checkbox的可选项列表. (2)ProgressDialog.一个用于显示进度圈或者进度条的dialog,继承自AlertDialog,所以它也支持按钮. (3)DatePickerDialog.用于让用户选择日期的dialog. (4)TimePickerDialog.用于让用户选择时间的dialog. 如果你需要定义自己的dialog,只需要继承dialog或者上面提到四个组件之一, 并且为新的dialog定义自己的布局就可以了. 2.显示dialog (1)一个dialog总是作为某个Activity的一部分被创建和显示.创建dialog当然是在Activity的onCreateDialog方法里做了,但是在创建不同用途的dialog却有章可循,推荐的方式是使用switch...case...结构.比如一个游戏里可能需要暂停和结束两种dialog,那我们的示例代码如下: static final int DIALOG_PAUSED_ID = 0; static final int DIALOG_GAMEOVER_ID = 1; protected Dialog onCreateDialog(int id) { Dialog dialog; switch(id) { case DIALOG_PAUSED_ID: // do the work to define the pause Dialog break; case DIALOG_GAMEOVER_ID: // do the work to define the game over Dialog break; default: dialog = null; } return dialog; } (2)当你想显示一个dialog的时候,使用showDialog(int id),参数id是你要显示的dialog的ID. (3)如果想在每次打开dialog的时候显示的内容有所不同,你应该考虑使用onPrepareDialog(int,Dialog)方法.它会在每次打开dialog时被调用,而不是像 onCreateDialog那样只在创建时被调用. (4)注意:如果你在onCreateDialog方法之外创建一个dialog,它不会默认被绑定到当前的Activity,但是你可以通过setOwnerActivity(Activity)方法来强制绑定. 3.关闭dialog (1)当你打算关闭一个dialog时,在dialog对象上调用dismiss()方法或者直接在Activity里调用dismissDialog(int)方法都可以达到这个目的. 实际上他俩是完全一样的,下面是dismissDialog方法的代码: public final void dismissDialog(int id) { if (mManagedDialogs == null) { throw missingDialog(id); } final Dialog dialog = mManagedDialogs.get(id); if (dialog == null) { throw missingDialog(id); } dialog.dismiss(); } (如果你正在使用onCreateDialog(int)方法管理你所有的dialog的状态),每次使用dismissDialog(int)方法关闭dialog时,Activity还会保留此dialog的状态.如果你确信不再需要已经关闭的dialog对象或者清除先前的状态对你的程序非常重要,那么你应该使用removeDialog(int),它会清除所有指向这个dialog对象的引用并且关闭它(如果这个dialog正在显示的话).下面是removeDialog方法的代码: public final void removeDialog(int id) { if (mManagedDialogs == null) { return; } final Dialog dialog = mManagedDialogs.get(id); if (dialog == null) { return; } dialog.dismiss(); mManagedDialogs.remove(id);//这句做了些什么呢,还没仔细看 } (2)使用dismiss listeners 如果想在关闭dialog的时候执行某些程序,那你应该考虑使用DialogInterface.OnDismissListener.使用方法如下代码所示: Dialog dialog = new Dialog(this); dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { public void onDismiss(DialogInterface dialog) { // write your performance here } }); dialog也有cancel状态,这是一种较特殊的情况.当用户点击"返回","取消"或者程序里明确调用了dialog.cancel()方法时发生.注意,这个时候, 先前注册的OnDismissListener仍然会被通知(即触发调用).如果你想发出明确的取消通知(而不是简单的关闭),那你就应该使用setOnCancelListener()方法注册一个DialogInterface.OnCancelListener来做这件事. 4.创建一个AlertDialog AlertDialog类继承于 Dialog 类.它是系统推荐的方式,能够构造出用户界面上的大多数dialog.有如下任何一个需求时,你应该考虑使用它: 显示一行标题文本; 显示一段文本消息; 让用户选择由一个`两个或者三个按钮代表的操作; 显示一个可选项列表(checkbox button或者radio button) AlertDialog.Builder子类用来创建一个AlertDialog.首先使用new AlertDialog.Builder(this)来创建一个Builder对象,然后使用它的公有 接口方法设置AlertDialog的所有属性.完成后可以通过builder.create()来得到新创建的dialog.下面是使用AlertDialog.Builder类来创建不同的AlertDialog的方法: (1)带button的Dialog AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { MyActivity.this.finish(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); 注意:这里的按钮有三类setPositiveButton,setNegativeButton,setNeutralButton, 每一类只允许添加一次, 也就是最多三个按钮.按钮的种类 名称只是帮助我们区分对待它们,与它们的实际功能(由我们自己在onClick方法里定义)无关. (2)添加一个列表 这个比较简单,给出代码示例 final CharSequence[] items = {"Red", "Green", "Blue"}; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Pick a color"); builder.setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); } }); AlertDialog alert = builder.create(); (3)添加checkbox 和 radio 按钮 在dialog里创建多选和单选列表应分别使用setMultiChoiceItems()和setSingleChoiceItems()方法.下面是创建一个单选项列表的代码: final CharSequence[] items = {"Red", "Green", "Blue"}; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Pick a color"); builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); } }); AlertDialog alert = builder.create(); 其中,setSingleChoiceItems()方法里第二个参数的意思是默认时选中哪一项,-1表示默认不选中任何一项. 注意:这样的情况下,用户可能希望这些值能被记忆并且恢复.要持久化存储这些选项的值,须借助android的数据存取技术. (4)创建ProgressDialog ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "", "Loading. Please wait...", true); 第一个参数为应用程序的Context(上下文);第二个参数为dialog的title;第三个参数是要显示的消息文本;the last parameter is whether the progress is indeterminate. ProgressDialog的默认样式是一个旋转的轮子.如果要创建一个能显示即时进度的工具条,需要更多一点的代码: ProgressDialog progressDialog; progressDialog = new ProgressDialog(mContext); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage("Loading..."); progressDialog.setCancelable(false); 这个代码在我测试的时候不能直接运行,会报出以下异常: E/AndroidRuntime( 278): Uncaught handler: thread main exiting due to uncaught exception E/AndroidRuntime( 278): android.view.WindowManager$BadTokenException: Unable to add window -- token 解决办法是把第二行换成下面这样就可以了: progressDialog = new ProgressDialog(DialogActivity.this);//这里要写程序中Activity的名字 (5)创建自定义的Dialog 根据使用基类的不同可以分作两类: 使用Dialog类构造; 使用AlertDialog类构造 两种类别的不同在于,前者的Title不能为空.如果你不设置title里的文字,它占据的空间会空着,这样显然不美观.而用后面一种方法就不会出现这种问题,不设置title,Dialog里就不显示,不影响美观.所以,还是回到那句话,更推荐使用AlertDialog组件. 5.接口收集 (1)Activity里与其相关的方法: protected Dialog onCreateDialog(int id) protected void onPrepareDialog(int id, Dialog dialog) public final void showDialog(int id) public final void dismissDialog(int id) public final void removeDialog(int id) (2)android.content.DialogInterface: interface OnCancelListener interface OnDismissListener interface OnShowListener interface OnClickListener interface OnMultiChoiceClickListener interface OnKeyListener (3)/android-src/frameworks/base/core/java/android/app/Dialog.java类及其子类里的所有方法 本文转自chainli 51CTO博客,原文链接:http://blog.51cto.com/lichen/495174,如需转载请自行联系原作者

优秀的个人博客,低调大师

Linux记录—进程相关学习

查看进程命令 ps -aux 常用组合命令,和Shall的 | grep 查询相关进程信息 -l 仅查看与自己相关的进程 详细信息中STAT代表了进程的状态: R:正在被cpu运行或者就绪的状态; S:处于等待状态中的进程,一旦被该进程等待的资源释放,马上进入运行状态 D:不可中断的睡眠状态,只能用wake_up()函数唤醒。 T:当收到SIG信号会进入暂停/运行状态 Z:僵尸状态:进程已经终止,但是父进程还没有询问其状态不可被kill。 top:动态查看内存变化 常用:top -b -n 3 >/tmp/top.txt 将top信息进行三次并输出到文件中。 pstree:查看进程树 常用:-Aup阿斯科码显示 进程管理 kill : 发送信号 -15:已正常的方式终止一个进程。默认 -9:立刻强制终止一个进程 -1:守护进程重启,非守护进程则终止进程 killall:杀死多个进程 系统资源监控: free -t 内存使用情况 uname:属性内核信息-a全部信息 uptime:观察系统启动时间与工作负载 netstat:网络监控 -antp vmstat: cpu/内存/磁盘输入输出状态 1 4 1秒刷新一次显示4行后不显示了 其他 tail -F filename 检测文件状态 bg/fg 将任务切换前台后台 & 在任何命令加上后可以使这条命令在后台执行。 jobs 显示后台的程序。

优秀的个人博客,低调大师

Android学习笔记--Service初步

1.Service是什么 是一个应用程序组件 没有图形化界面 通常处理一些耗时较长的操作 可以是使用service更新ContnetProvider.发送intnet以及启动系统的通知等等 2.Service不是什么 不是一个单独的进程 不是一个线程 3.Service生命周期 4.启动和停止Service的方法 服务例:publicclassFirstServiceextendsService{ @Override PublicIBinderonBind(Intentintent){ System.out.println("ServiceonBind"); Returnnull; } @Override PublicvoidonCreate(){ super.onCreate(); System.out.println("ServiceonCreate"); } //启动服务时方法 @Override PublicintonStartCommand(Intentintent,intflage,intstartId){ System.out.println("flags-->"+flags); System.out.println("startId-->"+startId); System.out.println("serviceonStartCommand"); ReturnSTART_NOT_STICKY; } @Override PublicvoidonDestroy(){ System.out.println("ServiceonDestroy"); super.onDestroy(); } } 在AndroidMnaifest.xml中注册服务:<serviceandroid:name=".FirstService"></service> 在Activity中调用Service例: 1.声明控件对象(略) 2.获得控件对象(略) 3.绑定事件(略) 4.创建监听器对象 //启动服务 PublicvoidonClick(Viewv){ Intentintent=newIntent(); intent.setClass(Activity.this,FirstService.class); startService(intent); } //停止服务 PublicvoidonClick(Viewv){ Intentintent=newIntent(); intent.setClass(Activity.this,FirstService.class); stopService(intent); } 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360561,如需转载请自行联系原作者

优秀的个人博客,低调大师

iOS学习——Hello iOS(二)

前面写了iOS开发环境搭建,只简单提了一下安装Xcode,这里再补充一下,点击下载Xcode的dmp文件,稍等片刻会有图一(拖拽Xcode至Applications)的提示,拖拽至Application即可,在Finder-应用程序-Xcode找到Xcode图标。点击Xcode图表,下一步操作即可进入开发界面。 图一(拖拽Xcode至Applications) 安装完Xcode,首先熟悉一下Xcode界面(这张是网上看到的一张图): 从上图看,Xcode和开发windows phone的Visual Studio、开发Android的Eclipse很像,如果是从那两个方向转过来做iOS开发的应该很快就能熟悉。 创建iOS项目: 1. 打开XCode,选择File->New Project,然后选择iOS->Application->Single View Application,然后点Next,如下图所示: 从上图看出,可以创建7种项目,我也是初学者,不能一一说出他们的不同,等熟悉了再补充。 2. 填写应用信息 Product Name:项目名称; Organization Name:组织名,一般显示计算机名; Company Identifier: 公司标示,此处输入一个唯一标示即可,也可以在项目中统一修改; Class Prefix: 默认类前缀,为了避免与其他类混淆,此处最好输入一个前缀名称,默认使用全大写字母,保留为空也可以; Device : 设备类型,可以选择“iPhone”“iPad”或者“Universal”(通用,同时支持iPhone和iPad) ; Storyboard: 是Xcode 4.x新增特性,是以前版本的xib的一个扩展升级,让程序的UI设计更加的简化;注意:基于Storyboard的应用只能在iOS5以上版本的设备上运行。 ARC: 是Xcode 4.x新增特性,对于以前版本的iOS程序员每alloc一个对象,都会下意识地先去release它,这是一个非常讨厌的事情。现在有了 ARC,一切都变得更加简单,程序员可以更加专注地处理自己应用的表现。 Include Unit Tests:生成项目时会包含测试包。 生成项目: 项目结构如下图: 选择MainStoryboard_iPhone.storyboard,初始时是一个空白,选择右下角的Label标签,双击,修改标签,点上面的运行按钮,模拟器就出现了HelloiOS,自己没写一行代码。Xcode开发工具还是很强大的。 /** * @author 张兴业 * http://blog.csdn.net/xyz_lmn * iOS入门群: 83702688 * android开发进阶群: 241395671 * 我的新浪微博: @张兴业TBOW */ 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/1230739 ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Intent过滤器学习

Intent过滤器是一种根据Intent中的动作(Action)、类别(Categorie)和数据(Data)等内容,对适合接收该接收Intent的组件进行和筛选的机制,Intent过滤器还可以匹配数据类型、路径和协议,还包括可以用来确定多个匹配项优先级(Prprity),应用程序的Activity组件、Service组件和BroadcaseReceiver都可以注册Intent过滤器,这样,这些组件在特定的数据格式上则可以产生相应的动作。 注册过滤在AndroidManifest.xml文件中定义 Intent节点属性 1.<action>:android:name--->指定组件所能响应的动作,用字符串表示,通常使用JAVA类名和名的完全限定名构成 2.<category>: android:category -->指定以何种方式去服务Intent请求的动作<一个程序中可以有多个Category标签哦> 3.<data>: 3.1:Android:host -->指定一个有效的主机名 3.2:android:mimetype -->指定组件能处理的数据类型 3.3:android:path -->有效的URI路径名 3.4:android:port -->主机的有效端口号 3.5:android:schme-->所需要的特定的协议 Android系统提供的类别(Category) ALTERNATIVE:Inent数据默认动作的一个可替换的执行方法 DRLRVYRF_ALTERNATIVE:和ALTERNATIVE类似,但替换的执行方法还是指定的,而是被解析出来的 BROWSABLE:声明Activity可以由浏览器启动 DEFAULT:为Intent过滤器中定义的数据提供默认动作 HOME:设备启动后显示的第一个Activity LAUNCHER:在应用程序启动时首先被显示 AndroidManifest.xml文件中的每个组件的<intent-filter>都被解析成一个Intent过滤器对象,当应用程序安装到Android系统时,所有的组件和Intent过滤器都会注册到Android系统中,这样,Android系统便乱箭了如何将任意一个Intent请求通过Intent过滤器映射到相应的组件上。 Intent到Intent过滤器的映射过程称为:“Intent解析”,Intent解析的匹配规则如下: 1.Android系统把所有应用程序包中的Intent过滤器集合在一起,形成一个完整的Intent过滤器列表。 2.在进行匹配时,Android系统会将列表中所有Intent过滤器的“动作”和“类别”与Intent进行匹配,任何不匹配的Intent过滤器都将被过滤掉,没有指定动作的Intent过滤器可以匹配任何的Intent,但是没有指定"类别"的过滤器只能匹配没有“类别”的Intent….吼吼。。。 3.把Intent数据的Uri的每个子部与Intent过滤器的<data>标签中的属性 进行匹配,如果<data>标签指定了协议、主机名、路径名或或MIME的类型,那么这些属性都要与Intent的Uri数据部分进行匹配,任何不匹配的Intent过滤器都会被过滤掉。 4.如果Intent过滤器多于一个,则可以根据在<inter-filter>标签中定义的优先级标签来对Intent过滤器进行排序,优先级最高的Intent过滤器将被选择。 Intent的另一种用途是改善广播消息。应用程序与Android系统都可以用Intent改善广播消息,如果应用程序注册了BroadcastReceiver,则可以接收到指定的广播消息。 String UNIQUE_STRING="com.mzh.www.BroadcastReceiverDemo" Intent intent = new Intent(UNIQUE_STRING); intent.putExtra("key1","XXX"); intent.putExtra("key2","YYY"); sentBroadCast(intent); 在构造Intent对象时必须用一个全局唯一的字符串标识其要执行的动作,通常使用应用程序包的名称,如:UNIQUE_STRING BroadcastReceiver用于监听广播消息,可以在全局文件或代码中注册,如: public class MyBroadcastReceiver extends BroadcastReceiver{ @Override //此方法必须重写 public void onReceiver(Context context, Intent intent ){ 此处省略一万字,,,吼吼。。 } } 此处:onReceiver()方法必须要在5秒钟执行完毕,否则Android系统会认为该组件失去响应,并提示用户执行强制关闭的 在xml文件中注册广播接收器: through the<receiver>tag in your AndroidManifest.xml. <receiver android:name=".继承BroadcastReceiver的类名"> <intent-filter> <action android:name="此处为sentBroadCast(intent)的值一标识"> </intent-filter> </receiver> 本文转自华华世界 51CTO博客,原文链接: http://blog.51cto.com/mzh3344258/733362 ,如需转载请自行联系原作者

优秀的个人博客,低调大师

rpc协议之学习路线

RPC(Remote Procedure Call,远程过程调用)框架是分布式服务的基石,实现RPC框架需要考虑方方面面。其对业务隐藏了底层通信过程(TCP/UDP、打包/解包、序列化/反序列化),使上层专注于功能实现;框架层面,提供各类可选架构(多进程/多线程/协程);应对设备故障(高负载/死机)、网络故障(拥塞/网络分化),提供相应容灾措施。 RPC节点间为了协同工作、实现信息交换,需要协商一定的规则和约定,例如字节序、压缩或加密算法、各字段类型。通信协议的应用随处可见,例如我们对可选信息或字段经常使用TLV进行编码,HTTP、FTP等协议基于可读文本的 "Field: Value" 格式,各种系统也经常使用json、XML格式完成相互间通信。 不同的通信协议适用于不同的应用场景,比如内部系统的交互我们选择json,一来可读性较好,二来各种语言都提供了解析json的库、方便编码。Google Protocol Buffers是生成环境中常用的通信协议,除了可以设定Client/Server间通信格式,Protocol Buffers还对数据进行压缩,节省传输流量、加快传输速度。下面我们来了解Google Protocol Buffers。 RPC RPC框架实现 - 通信协议篇 http://www.cnblogs.com/bangerlee/p/4486429.html 本文转自heavenseahill 51CTO博客,原文链接:http://blog.51cto.com/shower/1974171,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android学习笔记--Scoket编程

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 1.什么是Socket Socket英文意为"插座" 所谓Scoket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄 应用程序通常通过"套接字"向网络发出请求或者应答网络请求 2.Socket基本通信模型 3.使用基于TCP协议的Socket ServerSocketActivity代码例: 1.声明控件对象(略) 2.获得控件对象(略) 3.绑定事件(略) 4.创建监听器对象 PublicvoidonClick(Viewv){ NewServerThread().start(); } //TCPserver ClassServerThreadextendsThread{ Publicvoidrun(){ //声明一个serverSocket对象 ServerSocketserverSocket=null; Try{ //创建serverSocket对象并在4567端口监听 serverSocket=newServerSocket(4567); //调用serverSocket的accept方法,接受客户端所发送的请求 Socketsocket=serverSocket.accept();//阻塞函数 //从socket当中得到inputstream对象 InputStreaminputStream=socket.getInputStream(); Bytebuffer[]newbute[1024*4]; Inttemp=0; //从inputStream当中读取客户端所发送的数据 While((temp=inputStream.read(buffer))!=-1){ System.out,println(newString(buffer,0,temp)); } }catch(Execptione){ e.printStackTrace(); }finally{ Try{ serverSocket.close(); }catch(IOExecptione){ e.printStackTrace(); } } } } TCPClient代码例: Publicstaticvoidmain(String[]args){ Try{ //创建一个Socket对象,指定服务器端的ip地址和端口号 Socketsocket=newSocket("192.168.1.1",4567); //使用InputStream读取硬盘上的文件 InputStreaminputStream=newFileInputStream("F://file/words.txt"); //从Socket上得到outputStream outputStreamoutputStream=socket.getOutputStream(); Bytebuffer[]=newbyte[4*1024]; Inttemp=0; //将inputStream的数据取出并写入到outputStream While((temp=inputStream.read(buffer))!=-1){ outputStream.write(buffer,0,temp); } outpurStream.flush(); }catch(Execptione){ e.printStackTrace(); } } //UDPServer ClassServerThreadextendsThread{ Publicvoidrun(){ Try{ //创建一个DatagramSocket对象,并制定监听端口号 DatagramSocketsocket=newDatagramSocket(4567); Bytedata[]=newbyte[1024]; //创建一个空的DatagramPacket对象 DatagramPacketpacket=newDatagramPacket(data,data.length); //使用receive方法接受客户端所发送的数据 Socket.receive(packet);//阻塞方法 Stringresult=newString(packet.getData(),packet.getOffset(),packet.getLength());//设置数据偏移量,得到该次数据的长度 System.out.println("result-->"+result); }catch(Execptione){ e.printStackTrace(); } } } //UDPClient Publicstaticvoidmain(String[]args){ Try{ //创建一个DatagramSocket对象,并制定监听端口号 DatagramSocketsocket=newDatagramSocket(456 7); InetAddressserverAddress=InetAddress.getByName("192.168.1.1"); Stringstr="hello"; Bytedata[]=str.getBytes(); DatagramPacketpacket=newDatagramPacket(data,data.length,serverAddress,4567); Socket.send(packet); }catch(Execptione){ e.printStackTrace(); } } 4.使用基于UDP协议的Socket 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360562,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android学习笔记--程序调试

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 1.DDMS的使用 LogCat的VerboseDebugInfoWarningError的功能 增加过滤器createfilter=>system.out 通过fileexplorer功能实现文件的取出,放入 2.常见程序调试 A)多多查看DDMS的log和java中的方式相同 B)使用Log类输出各类信息 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360570,如需转载请自行联系原作者

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册