在使用代码模板产生代码时,CodeSmith引擎背后使用了不少对象来帮助代码的生成,其中常用的有
- CodeTempate (类似于Asp.Net的Page类)
- Progress 用于显示代码生成的进度
- CodeTemplateInfo 可以返回关于当前模板自身的一些信息。
本篇介绍CodeTemplate ,CodeTemplate代表了由CodeSmith引擎处理的代码模板对象,可以通过CodeTemplate对象直接和CodeSmith引擎交互,比如:
- 使用 GetFileName 修改模板生成的缺省文件名
- 使用 Render method 把模板的输出到多个文件中
- 通过 events 把代码插入到CodeSmith引擎处理模板的过程中。
- 通过 Response 属性直接在输出文件中写内容。
使用GetFileName修改模板输出的文件名
在前面的例子CodeSmith 使用教程(2): 编写第一个代码模板 我们已经使用GetFileName修改过输出的文件名,比如在你的模板中定义了一个ClassName属性,可以通过GetFileName 把模板输出的缺省文件名改成类名
<%@ Template Language="C#" TargetLanguage="Text" %> <%@ Property Name="ClassName" Type="System.String" Default="ClassName" %> This template shows off how to override the GetFileName method. <script runat="template"> public override string GetFileName() { return ClassName + ".cs"; } </script>
重载ParseDefaultValue 方法
在定义属性的缺省值时,有时有些属性的缺省值可能无法从String转换,此时可以通过重载ParseDefaultValue 方法,这个方法会被CodeSmith引擎中处理每个属性时调用,如果你重载了这个方法,可以按照你自己的逻辑来处理属性的缺省值。
重载Render 方法
CodeTemplate的Render方法是CodeSmith引擎生成最终输出时调用的,可以通过重载这个方法来修改输出的内容或是把输出写到多个文件中。
比如下面代码除了生成缺省的输出外,还把输出写到另外两个文件中:
<%@ CodeTemplate Language="C#" TargetLanguage="Text" Description="AddTextWriter Demonstration." %> <%@ Import Namespace="System.IO" %> //This template demonstrates using the AddTextWriter method //to output the template results to multiple locations concurrently. <script runat="template"> public override void Render(TextWriter writer) { StreamWriter fileWriter1 = new StreamWriter(@"test1.txt", true); this.Response.AddTextWriter(fileWriter1); StreamWriter fileWriter2 = new StreamWriter(@"test2.txt", true); this.Response.AddTextWriter(fileWriter2); base.Render(writer); fileWriter1.Close(); fileWriter2.Close(); } </script>
注意调用基类的base.Render,否则你就不会输出到缺省的文件。本例下载
由此带来三个问题:
l 回收规则: 什么时候回收与回收哪一个
l 避免误杀: 如何阻止被回收
l 数据恢复与保存: 被回收了怎么办
Android将进程分为6个等级,它们按优先级顺序由高到低
依次是:
1.前台进程( FOREGROUND_APP)
2.可视进程(VISIBLE_APP )
3. 次要服务进程(SECONDARY_SERVER )
4.后台进程 (HIDDEN_APP)
5.内容供应节点(CONTENT_PROVIDER)
6.空进程(EMPTY_APP)
特征:
1.如果一个进程里面同时包含service和可视的activity,那么这个进程应该归于可视进程,而不是service进程.
2.另外,如果其他进程依赖于它的话,一个进程的等级可以提高.例如,一个A进程里的service被绑定到B进程里的组件上,进程A将总被认为至少和B进程一样重要.
3.系统中的phone服务被划分到前台进程而不是次要服务
进程.
android4.0的ProcessList.java中
static final int HIDDEN_APP_MAX_ADJ = 15;
static int HIDDEN_APP_MIN_ADJ = 9;
static final int SERVICE_B_ADJ = 8;
static final int PREVIOUS_APP_ADJ = 7;
static final int HOME_APP_ADJ = 6;
static final int SERVICE_ADJ = 5;
static final int BACKUP_APP_ADJ = 4;
static final int HEAVY_WEIGHT_APP_ADJ = 3;
static final int PERCEPTIBLE_APP_ADJ = 2;
static final int VISIBLE_APP_ADJ = 1;
static final int FOREGROUND_APP_ADJ = 0;
static final int PERSISTENT_PROC_ADJ = -12;
static final int SYSTEM_ADJ = -16;
static final int MIN_HIDDEN_APPS = 2;
static final int MAX_HIDDEN_APPS = 15;
在android中以进程的oom_adj值也就代表了它的优先级.
oom_adj值越高代表该进程优先级越低. Init.rc中:
回收时机:
private final int[] mOomAdj = new int[] {
FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, HIDDEN_APP_MAX_ADJ
};
// HVGA or smaller phone with less than 512MB. Values are in KB.
private final long[] mOomMinFreeLow = new long[] {
8192, 12288, 16384,
24576, 28672, 32768
};
// These are the high-end OOM level limits. This is appropriate for a
// 1280x800 or larger screen with around 1GB RAM. Values are in KB.
private final long[] mOomMinFreeHigh = new long[] {
32768, 40960, 49152,
57344, 65536, 81920
};
通过计算最大和最小值,得出8084,10114,12144,14192,16222,20264
对应的mOomAdj里成员的内存阈值,一旦低于该值,Android
便开始按顺序关闭相应的进程 .
同时把计算结果保存在
cat /sys/module/lowmemorykiller/parameters/minfree
具体的回收实现在ActivityManagerService.java中的函
数trimApplications()
1.首先移除package被移走的无用进程.
2.基于进程当前状态,更新oom_adj值,然后进行以下操作.
l移除没有activity在运行的进程
l如果AP已经保存了所有的activity状态,结束这个AP.
3.最后,如果目前还是有很多activities 在运行,那么移除那些activity状态已经保存好的activity.
更新oom_adj的值
Android kernel中的low memory killer
Android的Low Memory Killer根据需要(当系统内存短
缺时)杀死进程释放其内存,源代码在
kernel/drivers/misc/lowmemorykiller.c
简单说就是寻找一个最合适的进程杀死,从而释放
它占用的内存.
最合适:
•oom_adj越大
•占用物理内存越多
一旦一个进程被选中,内核会发送SIGKILL信号将之杀死.
for_each_process(p) {
……
if(selected == NULL || p->oomkilladj > selected->oomkilladj ||
(p->oomkilladj == selected->oomkilladj &&
tasksize > selected_tasksize))
{
selected = p;
}
}
if(selected != NULL) {
force_sig(SIGKILL, selected);
}
查看LRU列表:Adb shell dumpsys activity
当activitydemo在前台时:
包含Service的进程的优先级比较高,在computeOomAdjLocked
中将其分为了两小类:
static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
if (adj > SECONDARY_SERVER_ADJ) {
adj = SECONDARY_SERVER_ADJ;
app.adjType = "started-services";
app.hidden = false;
}
}
if (adj > SECONDARY_SERVER_ADJ) {
app.adjType = "started-bg-services";
}
}
完全让进程不被kill是不可能的,我们可以通过一些操作
,使进程被kill的几率变小:
1.提高进程的优先级:
l后台操作采用Service形式,因为一个运行着service的进程比一个运行着后台activity的等级高。
l按back键使得进程中的activity在后台运行而不是destory,需重载back按键(没有任何activity在运行的进程优先被杀).
l依赖于其他优先级高的进程.
强制修改进程属性:
•在程序中设置setPersistent(true);
•在project的AndroidManifest.xml的<application>中加入属性android:persistent="true"
android:persistent(SDK)
Whether or not the application should remain running at all times . The default value is "false". Applications should not normally set this flag; persistence mode is intended only for certain system applications(phone,system).
1.使用killProcess (int pid)可以杀死指定PID的进程
public void onClick(View v) {
android.os.Process.killProcess(android.os.Process.myPid());
}
使用System.exit(0);可以达到同样的效果.
2.使用finish()可以杀死当前的activity
1. 保存资料:最好在每次Activity 运行到onPause或
onStop状态时先保存资料,然后在onCreate时将资
料读出来(生命周期方法).
2. OnSaveInstanceState(非生命周期方法)
onRestoreInstanceState
已有 0 人发表留言,猛击->>这里<<-参与讨论
ITeye推荐
- —软件人才免语言低担保 赴美带薪读研!—
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
<script type="text/javascript" src="/blog_article/jquery-1.8.3.js"></script>
<style>
*{
margin:0;
padding:0;
}
ul{
list-style:none;
}
#goods_category{
width:240px;
margin-top:10px;
margin-left:10px;
border:1px solid #ddd;
position:fixed;
}
h4, ul{
padding-top:5px;
padding-bottom:5px;
padding-left:10px;
}
h4.all_goods{
background-color:#900;
color:#fff;
padding-left:10px;
}
li{
display:inline-block;
padding-right:5px;
padding-top:2px;
padding-bottom:2px;
color:#666;
}
</style>
</head>
<body>
<div id="goods_category">
<h4 >所有商品分类</h4>
<dl >
<dd>
<h4>服装/内衣/配件</h4>
<ul>
<li>女装</li>
<li>女装</li>
<li>女装</li>
<li>女装</li>
<li>女装</li>
<li>女装</li>
<li>女装</li>
<li>女装</li>
<li>女装</li>
<li>女装</li>
</ul>
</dd>
<dd>
<h4>鞋/箱包</h4>
<ul>
<li>女鞋</li>
<li>女鞋</li>
<li>女鞋</li>
<li>女鞋</li>
<li>女鞋</li>
<li>女鞋</li>
<li>女鞋</li>
<li>女鞋</li>
<li>女鞋</li>
<li>女鞋</li>
</ul>
</dd>
<dd>
<h4>珠宝饰品/手表眼镜</h4>
<ul>
<li>珠宝</li>
<li>珠宝</li>
<li>珠宝</li>
<li>珠宝</li>
<li>珠宝</li>
<li>珠宝</li>
<li>珠宝</li>
<li>珠宝</li>
<li>珠宝</li>
<li>珠宝</li>
</ul>
</dd>
<dd>
<h4>化妆品</h4>
<ul>
<li>护肤</li>
<li>护肤</li>
<li>护肤</li>
<li>护肤</li>
<li>护肤</li>
<li>护肤</li>
<li>护肤</li>
<li>护肤</li>
<li>护肤</li>
</ul>
</dd>
<dd>
<h4>运动户外</h4>
<ul>
<li>运动鞋</li>
<li>运动鞋</li>
<li>运动鞋</li>
<li>运动鞋</li>
<li>运动鞋</li>
<li>运动鞋</li>
</ul>
</dd>
<dd>
<h4>手机数码</h4>
<ul>
<li>手机</li>
<li>手机</li>
<li>手机</li>
<li>手机</li>
<li>手机</li>
<li>手机</li>
<li>手机</li>
<li>手机</li>
</ul>
</dd>
<dd>
<h4>家用电器</h4>
<ul>
<li>大家电</li>
<li>大家电</li>
<li>大家电</li>
<li>大家电</li>
<li>大家电</li>
<li>大家电</li>
</ul>
</dd>
<dd>
<h4>家具建材</h4>
<ul>
<li>灯具</li>
<li>灯具</li>
<li>灯具</li>
<li>灯具</li>
<li>灯具</li>
<li>灯具</li>
<li>灯具</li>
<li>灯具</li>
<li>灯具</li>
</ul>
</dd>
<dd>
<h4>家纺/居家</h4>
<ul>
<li>四件套</li>
<li>四件套</li>
<li>四件套</li>
<li>四件套</li>
<li>四件套</li>
<li>四件套</li>
</ul>
</dd>
<dd>
<h4>母婴玩具</h4>
<ul>
<li>奶粉</li>
<li>奶粉</li>
<li>奶粉</li>
<li>奶粉</li>
<li>奶粉</li>
<li>奶粉</li>
<li>奶粉</li>
<li>奶粉</li>
</ul>
</dd>
<dd>
<h4>食品</h4>
<ul>
<li>零食</li>
<li>零食</li>
<li>零食</li>
<li>零食</li>
<li>零食</li>
<li>零食</li>
<li>零食</li>
<li>零食</li>
<li>零食</li>
</ul>
</dd>
<dd>
<h4>医药保健</h4>
<ul>
<li>保健</li>
<li>保健</li>
<li>保健</li>
<li>保健</li>
<li>保健</li>
<li>保健</li>
<li>保健</li>
<li>保健</li>
<li>保健</li>
</ul>
</dd>
<dd>
<h4>汽车配件</h4>
<ul>
<li>汽车</li>
<li>汽车</li>
<li>汽车</li>
<li>汽车</li>
<li>汽车</li>
<li>汽车</li>
<li>汽车</li>
</ul>
</dd>
<dd>
<h4>图书音像</h4>
<ul>
<li>考试</li>
<li>考试</li>
<li>考试</li>
<li>考试</li>
<li>考试</li>
<li>考试</li>
<li>考试</li>
<li>考试</li>
<li>考试</li>
</ul>
</dd>
<dd>
<h4>文化娱乐</h4>
<ul>
<li>电子凭证</li>
<li>电子凭证</li>
<li>电子凭证</li>
<li>电子凭证</li>
</ul>
</dd>
<dd>
<h4>手机/网游点卡</h4>
</dd>
</dl>
</div>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<p >end</p>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
</body>
<script>
/*
* 仿天猫首页-产品分类;
* ie8,ff,opera中测试可用,其余浏览器未测;
* ******made by keimon**********
* ********2013-01-14**********
*/
$(function(){
$('dd:odd').css('backgroundColor','#eee');
var scrollT=0;
$(window).scroll(function(e,scrollT){
var scrollTop = $(document).scrollTop();