在开发的过程中我们开发的页面可能会非常的长,我们在页面的两端放置了header和footer。这样的页面当我们滚动的时候,header和footer会随着滚动而滚到屏幕外,这时候我们如果想操做header和footer必须再滚动回去。jquerymobile为我们考虑了这种情况,在这种情况下我们可以点击屏幕,然后消失的header和footer就会出现,再次点击的时候就又会消失。如果我们正在文章的开头,无论我们怎么点击这个header都不会消失,footer在底部一样。下面我看一段代码:
<!DOCTYPE html> <html> <head> <title>Fixed Positioning Example</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/latest/jquery.mobile.min.css" /> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="http://code.jquery.com/mobile/latest/jquery.mobile.min.js"></script> </head> <body> <div data-role="page"> <div data-role="header" data-position="fixed"><h1>My Header</h1></div> <div data-role="content"> <p> ..........代表很长的内容,测试的时候请自己填满超过一个屏幕 </div> <div data-role="footer" data-position="fixed"><h4>My Footer</h4></div> </div> </body> </html>
在上面的代码中主要是在header和footer中添加了data-position属性,并将其值设置为fixed。这样是达到了我们的效果,但是同样还有一个问题,有时候我们可能在开始和结尾的时候也能全屏查看。这时候我们只需要对上面的代码进行一下改造,修改代码如下即可:
<div data-role="page" data-fullscreen="true">
在page上添加data-fullscreen,并且设置为true就可以了。这样当我们点击的时候会全屏,再点击的时候就会header、footer都出现了。同样这个全屏可以使用在一些图片的预览上。
适当stop和restart你的Activity对于确保用户的数据没有丢失是很重要的,下面是几个需要stop和restart一个Activity的情况:
- 用户打开最近使用窗口并且切换到其他app,这个Activity被stop,如果用户点击app icon或者从最近使用里返回app,Activity restart
- 从当前Activity打开另一个Activity,当前Activity在另一个Activity被创建时stop,当用户点返回键时,Activity restart
- 用户接电话时
与paused状态不同,stopped的状态下Activity完全不可见,用户焦点完全在另一个Activity或另一个App的Activity
Note: 因为系统会在内存中保持Activity实例,所以一般app不用实现onStop或者onRestart方法,甚至onStart方法,因为大多app比较简单,可能只实现onPause方法处理一些资源或者数据即可
Stop你的Activity当接收到onStop方法调用时,Activity不再可见,应该释放几乎所有不需要使用的资源,一旦Activity stop,如果系统需要回收系统能存,可能销毁实例,极端情况下,系统可能连onDestroy都不调用而直接杀掉进程,所以使用onStop方法处理会导致内存泄露的资源非常重要
即使onPause在onStop之前调用,也应该在onStop中处理更复杂,更耗CPU的操作,像写入数据库等
例如,下面例子像持久存储写入一个草稿
@Override protected void onStop() { super.onStop(); // Always call the superclass method first // Save the note's current draft, because the activity is stopping // and we want to be sure the current note progress isn't lost. ContentValues values = new ContentValues(); values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()); values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()); getContentResolver().update( mUri, // The URI for the note to update. values, // The map of column names and new values to apply to them. null, // No SELECT criteria are used. null // No WHERE columns are used. ); }
Activity处在stopped状态时,Activity对象会保持在内存中,不需要重新初始化resumed状态之前初始化的组件,系统也会跟踪布局中View的状态,所以如果在EditText中有输入也不必保存
Note: 即使系统在stopped状态下destroy你的Activity,View的状态仍然被保存在一个Bundle中,当用户再次回到这个Activity事例时还会存在
Start/Restart你的Activity当Activity从stopped状态到前台来,接到onRestart方法调用,系统也会调用onStart方法,因为每次Activity变得可见时系统都会调用onStart方法,无论创建还是restart,onRestart方法只是在stopped状态resume时才调用,所以可以在在其中执行一些特殊的恢复操作,例如用户长时间离开后,在onStart方法中确保系统状态是否可以是再好不过的了
@Override protected void onStart() { super.onStart(); // Always call the superclass method first // The activity is either being restarted or started for the first time // so this is where we should make sure that GPS is enabled LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); if (!gpsEnabled) { // Create a dialog here that requests the user to enable GPS, and use an intent // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action // to take the user to the Settings screen to enable GPS when they click "OK" } } @Override protected void onRestart() { super.onRestart(); // Always call the superclass method first // Activity being restarted from stopped state }
因为多数资源在onStop方法中释放,所以一般不用实现onDestroy方法,但也要确保所有可能导致内存泄露的资源已经被释放
4楼gareth_liao昨天 17:36不错 啊3楼cshanxiaoyi昨天 17:09嗯嗯嗯额2楼gdsfga昨天 11:16不错1楼fke888999昨天 08:55很好很好
uboot分析之配置过程
基于u-boot-2012.04.01.tar.bz2
一:
问:我们在编译uboot的时候,先是执行make smdkc100_config命令(配置),然后执行make命令(编译),那么make smdkc100_config过程是怎么实现的呢?
答:我们知道,在执行命令的时候,都直接和Makefile挂钩,打开uboot顶层目录下的Makefile,搜索发现了uboot的配置过程如下:(注意区别u-boot-1.1.6的)
%_config:: unconfig
@$(MKCONFIG) -A $(@:_config=)
这里可以看到%_config目标后面是双冒号,而我们平常看的只有一个冒号,这是Makefile 的双冒号规则,而平常我们见的单冒号就是普通规则。
Makefile中规定:一个目标可以出现在多个规则中。但是这些规则必须是同一类型的规则,要么都是普通规则,要么都是双冒号规则。而不允许一个目标同时出现在两种不同类型的规则中。双冒号规则和普通规则的处理的不同点表现在以下两方面:
1. 双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行。而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。
2. 当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。
uboot从2010.09版本开始工程结构发生变化,关于板子的配置信息都独立出来放在了boards.cfg文件中,这样在我们执行不同的“make <board_name>_config”时,都会执行
%_config:: unconfig
@$(MKCONFIG) -A $(@:_config=)
这个命令,但是uboot使用双冒号规则后,都会按照各自的<board_name>_config生成相应的目标文件,从而节省了Makefile的代码量。
(1).@的作用是:在执行这条命令的时候不进行显示;
(2).$(MKCONFIG)的作用是:取出变量MKCONFIG的值。变量MKCONFIG定义在该Makefile上面,具体如下:
MKCONFIG := $(SRCTREE)/mkconfig @即当前目录下的mkconfig
(3).$(@:_config=)的作用是:将目标文件名字中含有的_config的部分用等号后面的字符替换掉,这里=后面为空,所以其效果就是把_config去掉。
综上所述:
执行make smdkc100_config,最终会执行如下命令:
mkconfig -A smdkc100
------------------------------------
$1 $2
二:
紧接着,肯定是分析mkconfig脚本文件,打开uboot更目录下面的mkconfig脚本文件,观看分析:
(1).
/*定义一些变量供后面填充*/
arch=""
cpu=""
board=""
vendor=""
soc=""
options=""
(2).
/* $#:代表传入的参数的总个数
* -a:代表前后两个条件都要成立
*/
if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then @该条件是成立的,所以紧接着执行
line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
echo "make: *** No rule to make target \`$2_config'. Stop." >&2
exit 1
}
@对红色部分代码的注释:
这里是执行egrep命令( egrep命令是一个搜索文件获得模式,使用些命令可以任意搜索文件中的字符串和符号,也可以为你搜索一个多个文件的字符串,一个提示符可以是单个字符、一个字符串、一个字、一个句子。);
-i参数是指:当进行比较时忽略字符的大小写;
^是指:行首,用法举例。^[fuck]表示:以fuck开头的行;
[[:space:]]是指:空格或tab;
^[[:space:]]则是指:以空格或tab开头的行;
*则是指:匹配零个或多个先前字符。如:'*grep'匹配所有一个或多个空格后紧跟grep的行;
${2}是指:第二个参数的内容,即smdkc100;
||是指:和我们c语言的或的用法一样,前面成立的时候,后面不执行;
总结:
line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg`
就是指在boards.cfg文件中搜索以${2}(即smdkc100)开头的行,匹配成功后,把改行保存到变量line中,因此后面的${line}的内容就是:
smdkc100 arm armv7 smdkc100 samsung s5pc1xx
(3).
set ${line} @设置shell,就理解成重新录入参数,以此最终shell的参数如下:
smdkc100(目标) arm(平台) armv7(cpu架构) smdkc100(板子名字) samsung(厂商) s5pc1xx(功能)
-----------------------------------------------------------------
$1 $2 $3 $4 $5 $6
[ $# = 3 ] && set ${line} ${1} @如果传人的参数的总个数为3个,才执行set命令,不成立
(4).
while [ $# -gt 0 ] ; do // 如果参数个数大于0个,执行下面的,成立
case "$1" in // 类似于c中的switch,这里没有符号的case条件
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%_config}" ; shift ;;
-t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
*) break ;;
esac
done
[ $# -lt 4 ] && exit 1 // 如果参数个数小于4,退出
[ $# -gt 7 ] && exit 1 // 如果参数个数大于7,退出
(5).
// 该步骤就是给(1)中定义的变量进行赋值
CONFIG_NAME="${1%_config}" @CONFIG_NAME=smdkc100
[ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}" @BOARD_NAME=smdkc100
arch="$2" @arch=arm
cpu="$3" @cpu=armv7
if [ "$4" = "-" ] ; then @该if不成立
board=${BOARD_NAME}
else
board="$4" @board=smdkc100
fi
[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5" @vendor=samsung
[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6" @soc=s5pc1xx
[ $# -gt 6 ] && [ "$7" != "-" ] && {} @不成立
(6).
//该步骤就是打印大家常见的:Configuring for smdkc100 board...
if [ "$options" ] ; then
echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}"
else
echo "Configuring for ${BOARD_NAME} board..."
Fi
(7).
// 该步骤就是创建一些连接文件
rm -f asm @删除现有的asm连接文件
ln -s ../arch/${arch}/include/asm asm @重新让asm指向\arch\arm\include\asm
......
问:为什么要建立这样的连接文件呢?
答:是为了在源码中写代码的方便,比如:
#include <asm/type.h> //源码中的书写形式!!!!
但是当执行完配置命令后,就相当于#include <asm-arm/type.h>。这样方便支持多种建构
(8).
//该步骤就是创建一个头文件(即config.mk),用于顶层的Makefile的宏控
echo "ARCH = ${arch}" > config.mk
echo "CPU = ${cpu}" >> config.mk
echo "BOARD = ${board}" >> config.mk
[ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk
[ "${soc}" ] && echo "SOC = ${soc}" >> config.mk
*********************执行以上5句命令后,相当于config.mk中有类容****************************
ARCH = arm
CPU = armv7
BOARD = smdkc100
VENDOR =samsung
SOC = s5pc1xx
注意:
config.mk用于更目录的Makefile完成相关的配置筛选!!!
*******************************************************************************************
(9).
// 该步骤用于创建一个单板相关的头文件
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # 新建一个config.h文件
fi
/* 以下就是填充config.h中的内容了:>是新建、>>是追加 */
echo "/* Automatically generated - do not edit */" >>config.h
echo "#define CONFIG_${i}" >>config.h ;
cat << EOF >> config.h
#define CONFIG_BOARDDIR board/$BOARDDIR
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/${CONFIG_NAME}.h>
#include <asm/config.h>
EOF
************************执行以上几句命令后,相当于config.h中有类容***************************
/* Automatically generated - do not edit */
#define CONFIG_BOARDDIR board/samsung/smdkc100
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/smdkc100.h>
#include <asm/config.h>
注意:
config.h用于完成代码中相关配置的筛选!!!
*******************************************************************************************
三.编译过程(make)
再看Makefile.............................
该过程和u-boot-1.1.6的过程基本一样,这里不再重述。请自己阅读“u-boot-1.1.6的配置编译过程分析.doc”。
共享以前分析uboot时做的笔记,包括:
1.u-boot-1.1.6的配置编译过程分析.doc
2.u-boot-2012.04.01的配置编译过程分析.doc
3.u-boot-1.1.6完全注释,基本实现了逐行的注释。
...... // 后继更新的将直接上传群共享
请大家原谅哈,由于我们想建立一个uboot技术交流社区,
需要经费。故上述uboot笔记,需要9元钱购买,购买链接地址:
http://item.taobao.com/item.htm?spm=0.0.0.31.lHTZaH&id=17051965131
当然,为了让大家觉得花钱值得。大家购买后,可以凭借
购买的帐号,加入“uboot移植交流群”。
该群由我(韦东山LINUX视频的答疑助手@万勇)和吴伟东(韦东
山LINUX视频的答疑助手-小吴)负责,我们会在:
每周3晚上7点到10点和每周日(下午3点到6点和晚上8点到10
点)负责答疑。和大家一起学习uboot,实现逐行分析注释uboot。
我们建立该uboot技术交流群的宗旨是:
找些人在一起,为全天下的板子移植uboot!!!!
入群条件:
1.你是高手,可以无条件的入群。当然有考核的;
2.或者你是想学习的,购买“uboot完全注释”后,提供网名,入群