[转载]如何将List转换相应的Html(xsl动态转换)(二)

mikel阅读(1130)

[转载]如何将List转换相应的Html(xsl动态转换)(二) – JasenKin – 博客园.

紧跟着上一篇随笔,本文主要涉及到如何将xml与xsl动态转换成html,这个才是最关键的地方,所有的内容都是围绕这个主题来进行开展的。根据指定的xsl样式将List<T>转换相应的Html,相关的随笔如下:

(一)、将List<T>转换成DataTable

(二)、将Xml与Xsl动态转换成Html

(三)、设置以及控制Xsl的内容样式。

二、XslTransform的具体实现

XslTransform主要的职责为:将xml与xsl动态转换成html。其中,XslCompiledTransform 提供了很多方法可以进行相关的转换,但使用起来并不是十分方便,因此必须在该基础上来对目前的类进行相关封装以及提取。具体的代码如下:

1     public class XslTransform : IDisposable
2     {
3         public StringWriter StringWriter
4         {
5             get;
6             private set;
7         }
8
9         public StringReader XmlStringReader
10         {
11             get;
12             private set;
13         }
14
15         public StringReader XslStringReader
16         {
17             get;
18             private set;
19         }
20
21         public XslTransform()
22         {
23             this.StringWriter = new StringWriter();
24         }
25
26         public string Transfer(string xmlText, string xslText)
27         {
28             if (string.IsNullOrWhiteSpace(xmlText)
29                 || string.IsNullOrWhiteSpace(xslText))
30             {
31                 return string.Empty;
32             }
33             this.XmlStringReader = new StringReader(xmlText);
34             this.XslStringReader = new StringReader(xslText);
35
36             return TransferXmlAndXslToHtml();
37         }
38
39         private string TransferXmlAndXslToHtml()
40         {
41             try
42             {
43                 using (XmlTextWriter writer = new XmlTextWriter(this.StringWriter))
44                 {
45                     return ToHtml(writer);
46                 }
47             }
48             catch
49             {
50                 return string.Empty;
51             }
52         }
53
54         private string ToHtml(XmlTextWriter writer)
55         {
56             XslCompiledTransform xslTransform = new XslCompiledTransform();
57             xslTransform.Load(XmlReader.Create(this.XslStringReader));
58             xslTransform.Transform(XmlReader.Create(this.XmlStringReader), writer);
59
60             return this.StringWriter.ToString();
61         }
62
63         #region IDisposable 成员
64
65         public void Dispose()
66         {
67             this.Dispose(true);
68             GC.SuppressFinalize(this);
69         }
70
71         private void Dispose(bool disposing)
72         {
73             if (this.StringWriter != null)
74             {
75                 this.StringWriter.Dispose();
76             }
77             if (this.XslStringReader != null)
78             {
79                 this.XslStringReader.Dispose();
80             }
81             if (this.XmlStringReader != null)
82             {
83                 this.XmlStringReader.Dispose();
84             }
85         }
86
87         #endregion
88     }

XslTransform 类主要的方法为54-61行的代码,如下所示:

54         private string ToHtml(XmlTextWriter writer)
55         {
56             XslCompiledTransform xslTransform = new XslCompiledTransform();
57             xslTransform.Load(XmlReader.Create(this.XslStringReader));
58             xslTransform.Transform(XmlReader.Create(this.XmlStringReader), writer);
59
60             return this.StringWriter.ToString();
61         }

第57行加载XSL的样式文本,58行在原有基础上将XML转换成XmlTextWriter对象。其中XmlTextWriter在初始化时,StringWriter对象作为参数传递进去,如以下的43行代码:

43 using (XmlTextWriter writer = new XmlTextWriter(this.StringWriter))

因此直接返回this.StringWriter.ToString();就获取到了我们所需的Html了。

其次,XslTransform 类还有一个注意的要点:实现IDisposable接口主要是将用到的资源及时释放掉,避免造成其他影响。

三、Xsl文件的设置以及添加到资源文件中

(1)创建MapperInfoXslContent.xslt样式文件,内容如下(目前使用最简单的,不做任何处理的样式文件):

<!--?xml version="1.0" encoding="utf-8"?-->

demo
<table>
<tbody>
<tr>
<td>
<table style="border-collapse: collapse;" border="1px" cellspacing="0px" bordercolor="#000000">
<tbody>
<tr bgcolor="#9acd32">
<th width="80">Name</th>
<th width="80">Value</th>
<th width="80">Percent</th>
<th width="230">CreatedTime</th>
<th width="60">IsActive</th>
<th width="190">TargerUrl</th>
</tr>
<tr>
<td width="80" bgcolor="#ff00ff"></td>
<td width="80"></td>
<td width="80" bgcolor="#ff00ff"></td>
<td width="230"></td>
<td width="60" bgcolor="#ff00ff"></td>
<td width="190"></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>

(2)然后再创建XslResource.resx资源文件,将MapperInfoXslContent.xslt样式文件添加到XslResource.resx资源文件中,如下图所示:

四、转换后的效果

经过转换后得到的Html显示效果如下(测试过程中可以以HTML格式来查看字符串):

五、相关的单元测试

示例的单元测试代码如下(仅做了一些最基础的测试,验证内容是否存在):

[TestMethod()]
public void TransferTest()
{
string xmlText = GetXmlText();
string xslText = XslResource.MapperInfoXslContent;
string htmlContent = string.Empty;
using (XslTransform xslTransform = new XslTransform())
{
htmlContent = xslTransform.Transfer(xmlText, xslText);
}

Assert.IsTrue(!string.IsNullOrWhiteSpace(htmlContent));
Assert.IsTrue(htmlContent.Contains("true"));
Assert.IsTrue(htmlContent.Contains("false"));

for (int index = 0; index &lt; 3; index++)
{
Assert.IsTrue(htmlContent.Contains(
string.Concat("MapperInfoIndex", index.ToString())));
Assert.IsTrue(htmlContent.Contains(
string.Format(@"www.codeplex.com?Id={0}", index)));
Assert.IsTrue(htmlContent.Contains(index.ToString()));
}
}

private string GetXmlText()
{
List entities = CreateMapperInfos(3);
DataTable dataTable = EntityMapper.ToDataTable(entities);
DataSet dataSet = new DataSet("DataSet");
dataSet.Tables.Add(dataTable);

return dataSet.GetXml();
}

private List CreateMapperInfos(int count)
{
List entities = new List();
for (int index = 0; index &lt; count; index++)
{
entities.Add(new MapperInfo()
{
Name = string.Concat("MapperInfoIndex", index.ToString()),
IsActive = (index % 2 == 0 ? true : false),
CreatedTime = DateTime.Now,
Value = index,
Percent = GetPercent(index),
TargetUrl = string.Format(@"www.codeplex.com?Id={0}", index)
});
}

return entities;
}

private decimal? GetPercent(int index)
{
if (index % 2 == 0)
{
return index;
}

return null;
}

六、总结

上面涉及的仅仅是其中的一种,代码应该是比较精简的。还有另外一种采用XPathNavigator的,也就是笛子说的:“如果使用 XmlWriter 或 XmlDocument,则可以避开这个问题。另外,XslCompiledTransform.Transform 方法重载了几个版本中,如果我没记错的话,最应优先使用的是xml数据源为 XPathNavigator 的版本。”。关于这种情况,可以通过XmlDocument来创建相关的XPathNavigator对象,即:XPathNavigator navigator = XmlDocument.DocumentElement.CreateNavigator(),这种版本的我也重写了一份,但是好像没有转换成功,因此 就采用这种模式了。下一篇主要涉及到XSL样式的设计以及相关的函数、模板的应用。

[转载]快速开发新浪微博的firefox插件(上)

mikel阅读(958)

[转载]快速开发新浪微博的firefox插件(上) – Fei He – 博客园.

在开发这个插件之前,自己对JavaScript的使用也就是web page中简单的操作dom,而对于firefox插件开发一无所知,OAuth连听都没有听过。所以对于我眼前要干得事情我有两个难点,第一就是 firefox的插件机制,第二就是了解OAuth。

firefox的插件机制

对于一个firefox插件来说,我们首先需要了解的它的组织结构。打开一个firefox插件工程,你一般会看这么几个元素:chrome文件夹,defaults文件夹,chrome.manifest, install.rdf。

我们先从install.rdf说起,相比从文件名你就明白了这个文件是要干什么的。没错,这个文件就是firefox插件的安装文件。


<!--?xml version="1.0"?-->
flashcard@gmail.com
0.7
2
flashcard
Post the selected word to Sina weibo.
https://feihe.cnblogs.com
chrome://flashcard/skin/icon.png

Fei He

{ec8030f7-c20a-464f-9b0e-13a3a9e97384}
3.0
4.0.*

里面也就是对于你的firefox插件的一些描述信 息,其中比较关键的两个<em:id>, 在根节点description下的<em:id>是你的firefox插件的id,也就是说这个东西必须唯一(至少在你的firefox所 有插件中唯一),另一个位于<em:targetApplication>的<Description>下 的<em:id>则是firefox的id,这个是不能修改的。再就是<em:minVersion> 和<em:maxVersion>,它们用来描述你的firefox插件对于firefox版本的兼容性。

接着我们来了解defaults,一句话defaults就是你的firefox插件的preferences的default设置。

对于一个firefox插件最核心的部分就 是chrome.manifest和chrome文件夹。chrome.manifest有点像.NET的project文件,基本上就是对于整个 firefox插件所有元素的位置信息,而firefox本身就是通过这个这个manifest来定位具体的元素。那么一个firefox插件会包含那些 元素呢?打开chrome.manifest你就一目了然了。

overlay		chrome://browser/content/browser.xul    chrome://flashcard/content/overlay.xul
content		flashcard	chrome/content/flashcard/
skin	flashcard	classic	chrome/skin/classic/flashcard/

locale	flashcard	en-US	chrome/locale/flashcard/en-US/
style	chrome://global/content/customizeToolbar.xul	chrome://flashcard/skin/skin.css

这里面的结构基本都是行结构的,每一个行的头就是具体的firefox插件元素名称,而后面的是告诉firefox去那个位置查找这个元素。而这其中包含了这么几个元素:

  • overlay: 指向你的firefox插件的一个UI元素,包括contextmenu,toolbar,navigator bar之类。在上面的manifest中你看我这里指向了一个后缀名是xul的文件,其实它的全称是Xml User Interface。顾名思义就是使用xml的格式来描述UI。
<!--?xml version="1.0"?-->
<!--?xml-stylesheet href="chrome://flashcard/skin/skin.css" type="text/css"?-->

<script type="application/x-javascript">// <!&#91;CDATA&#91;
     mce:0
// &#93;&#93;></script>
<script type="application/x-javascript">// <!&#91;CDATA&#91;
     mce:1
// &#93;&#93;></script>
<script type="application/x-javascript">// <!&#91;CDATA&#91;
     mce:2
// &#93;&#93;></script>
<script type="application/x-javascript">// <!&#91;CDATA&#91;
     mce:3
// &#93;&#93;></script>

<script type="application/x-javascript">// <!&#91;CDATA&#91;
     mce:4
// &#93;&#93;></script>
<script type="application/x-javascript">// <!&#91;CDATA&#91;
     mce:5
// &#93;&#93;></script>
<script type="application/x-javascript">// <!&#91;CDATA&#91;
     mce:6
// &#93;&#93;></script>

上面是我用的一个overlay.xul, 我这里是给firefox的contextmenu加了一个新的menuitem,并使用separator和原有的menuitems分隔起来。这里的 文件名是可以随意取的,那是你起的名字必须在chrome.manifest中应用。到这里很多人好奇,那么你加的menuitem相应的行为在那里呢? 细心的你也许发现我这个xul中引用了一些JavaScript,而对于我们menuitem,firefox提供了2中方法去关联行为:第一种就是在 control的oncommand中直接指定control的行为;第二中是JavaScript中使用 document.getElementByID来获取control从而绑定行为:


document.getElementById("menuitem_flashcard_add").addEventListener("click", function(event){}, false);

并且,我也在这个文件中指定了css文件。其实对于xul文件中javascript和css的使用和html都基本一致。

  • content: 就是你的firefox插件的核心,包括javascript脚本和XUL
  • skin:即使皮肤,你可以在给你的插件做不同的皮肤,我的mainifest中指定了我使用classic的皮肤,所以我在skin文件夹下就应classic的文件夹来对应。
  • locale:国际化,对于我们firefox插件中需要需要国家化的UI control, 我们可以使用它的label属性,同时在chrome.manifest中指定的culture文件夹下定义dtd文件来对应,例如: overlay.xul中的control定义:

dtd文件的定义:

<!--ENTITY flashcard.menuitem.label "Post to flashcard"-->
  • 它们之间使用control的label属性关联,而overlay.xul具体和chrome.manifest指定culture文件夹下的那个dtd文件关联,你可以看到在我的overlay.xul中有这么一句定义:
  • style: 也就是overlay的一些样式,比如css。
  • 它们之间使用control的label属性关联,而overlay.xul具体和chrome.manifest指定culture文件夹下的那个dtd文件关联,你可以看到在我的overlay.xul中有这么一句定义:
  • style: 也就是overlay的一些样式,比如css。

你的firefox插件有了UI,也有了相 应的行为和样式,那么你还需要什么呢?需要存储,也就是你需要存储一些preferences信息或者其他的比如我这里我需要存储新浪微博中用户授权通过 之后获得的Oauth_token的相关信息。firefox对于存储提供了很多方式,你可文件存贮在特殊位置,或者使用SQLite这种肖的文件数据 库。另外一种最简单的也就是我采用的就是preferences的存贮。对于firefox插件,你可以在你的install.rdf中注 明你的preference文件,这样你可以让用户使用的preference文件做一些设置,并保存。而我这里我指希望使用preferences来存 贮,所以我并不希望用户看到它,那么我就不需要在install.rdf中注明。

preference文件也是一个xul文件,所以你也可以应用javascript和css,来对于你的preference中的control进行行为的绑定和样式的渲染。我这里的preference如下:

<!--?xml version="1.0"?-->
<!--?xml-stylesheet href="chrome://global/skin/" type="text/css"?-->

而这其中的preferences节点中的内容便是用来做preference存贮的,你可以像我一样通过

Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("Sina.WeiBo.")

来获得所有name前缀为Sian.Weibo的preference,然后调用它的 getCharPref(‘oauth.access_token’)来获取值,或者通过 setCharPref(‘oauth.access_token’)设置值,对于preference,MDN上有详细的API介绍。对于在 preference中引用javascript比较tricky的一点就是如果在你preference中使用prePanel,那么 javascript的引用代码一定要在prePanel后面,否则你的prePanel就什么都看不到了。

最后一点,有些时候也许你希望你的firefox插件在完成某些行为之后给用户一个notification,在firefox3中你可以使用普通 的notification或者alert,而在firefox4中你可以使用popupNotification,效果非常炫,而且还可以指定图片和相 应的action,使得用户在得到这个notification之后可以做进一步的行为。示例如下:

PopupNotifications.show(gBrowser.selectedBrowser, "flashcard-add",
        '"'+ selectedWord +'" 已经成功加入你的单词本',
        null, 
		{
			label: "确定",
			accessKey: "D",
			callback: function() {
			}	
		},
		[
			{
				label: "Reset",
				accessKey: "R",
				callback: function() {
					Browser.Preferences.clearUserPref("oauth.access_token");
					Browser.Preferences.clearUserPref("oauth.access_token_secret");
				}	
			},
		]);

而指定图片则要在css中

.popup-notification-icon[popupid="flashcard-add"] {
	list-style-image: url("chrome://flashcard/skin/icon.png");
}

这里是我在快速开发一个firefox插件中获得知识,如果你希望更详细的知识还是需要参考MDN。写到这里发现篇幅有点长,还是决定分为上,下两篇。下篇来讲Sina WeiBo的Oauth授权机制。

[转载]eclipse 最全快捷键 分享快乐与便捷

mikel阅读(574)

[转载]eclipse 最全快捷键 分享快乐与便捷 – 耿玉龙 – 博客园.

Ctrl+1 快速修复(最经典的快捷键,就不用多说了)
Ctrl+D: 删除当前行
Ctrl+Alt+↓ 复制当前行到下一行(复制增加)
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)
Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)
Alt+↑ 当前行和上面一行交互位置(同上)
Alt+← 前一个编辑的页面
Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)
Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性
Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)
Shift+Ctrl+Enter 在当前行插入空行(原理同上条)
Ctrl+Q 定位到最后编辑的地方
Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)
Ctrl+M 最大化当前的Edit或View (再按则反之)
Ctrl+/ 注释当前行,再按则取消注释
Ctrl+O 快速显示 OutLine
Ctrl+T 快速显示当前类的继承结构
Ctrl+W 关闭当前Editer
Ctrl+K 参照选中的Word快速定位到下一个
Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)
Ctrl+/(小键盘) 折叠当前类中的所有代码
Ctrl+×(小键盘) 展开当前类中的所有代码
Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用

Alt+/来代替)
Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)
Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没

有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)
Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)
Ctrl+Shift+F4 关闭所有打开的Editer
Ctrl+Shift+X 把当前选中的文本全部变味小写
Ctrl+Shift+Y 把当前选中的文本全部变为小写
Ctrl+Shift+F 格式化当前代码
Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反

之)
下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift

开头的了)
Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力

)
Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)
Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)
Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)
Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)
Alt+Shift+I 合并变量(可能这样说有点不妥Inline)
Alt+Shift+V 移动函数和变量(不怎么常用)
Alt+Shift+Z 重构的后悔药(Undo)
编辑
作用域 功能 快捷键
全局 查找并替换 Ctrl+F
文本编辑器 查找上一个 Ctrl+Shift+K
文本编辑器 查找下一个 Ctrl+K
全局 撤销 Ctrl+Z
全局 复制 Ctrl+C
全局 恢复上一个选择 Alt+Shift+↓
全局 剪切 Ctrl+X
全局 快速修正 Ctrl1+1
全局 内容辅助 Alt+/
全局 全部选中 Ctrl+A
全局 删除 Delete
全局 上下文信息 Alt+?
Alt+Shift+?
Ctrl+Shift+Space
java编辑器 显示工具提示描述 F2
java编辑器 选择封装元素 Alt+Shift+↑
java编辑器 选择上一个元素 Alt+Shift+←
java编辑器 选择下一个元素 Alt+Shift+→
文本编辑器 增量查找 Ctrl+J
文本编辑器 增量逆向查找 Ctrl+Shift+J
全局 粘贴 Ctrl+V
全局 重做 Ctrl+Y

查看
作用域 功能 快捷键
全局 放大 Ctrl+=
全局 缩小 Ctrl+-

窗口
作用域 功能 快捷键
全局 激活编辑器 F12
全局 切换编辑器 Ctrl+Shift+W
全局 上一个编辑器 Ctrl+Shift+F6
全局 上一个视图 Ctrl+Shift+F7
全局 上一个透视图 Ctrl+Shift+F8
全局 下一个编辑器 Ctrl+F6
全局 下一个视图 Ctrl+F7
全局 下一个透视图 Ctrl+F8
文本编辑器 显示标尺上下文菜单 Ctrl+W
全局 显示视图菜单 Ctrl+F10
全局 显示系统菜单 Alt+-

导航
作用域 功能 快捷键
java编辑器 打开结构 Ctrl+F3
全局 打开类型 Ctrl+Shift+T
全局 打开类型层次结构 F4
全局 打开声明 F3
全局 打开外部javadoc Shift+F2
全局 打开资源 Ctrl+Shift+R
全局 后退历史记录 Alt+←
全局 前进历史记录 Alt+→
全局 上一个 Ctrl+,
全局 下一个 Ctrl+.
java编辑器 显示大纲 Ctrl+O
全局 在层次结构中打开类型 Ctrl+Shift+H
全局 转至匹配的括号 Ctrl+Shift+P
全局 转至上一个编辑位置 Ctrl+Q
java编辑器 转至上一个成员 Ctrl+Shift+↑
java编辑器 转至下一个成员 Ctrl+Shift+↓
文本编辑器 转至行 Ctrl+L

搜索
作用域 功能 快捷键
全局 出现在文件中 Ctrl+Shift+U
全局 打开搜索对话框 Ctrl+H
全局 工作区中的声明 Ctrl+G
全局 工作区中的引用 Ctrl+Shift+G

文本编辑
作用域 功能 快捷键
文本编辑器 改写切换 Insert
文本编辑器 上滚行 Ctrl+↑
文本编辑器 下滚行 Ctrl+↓

文件
作用域 功能 快捷键
全局 保存 Ctrl+X
Ctrl+S
全局 打印 Ctrl+P
全局 关闭 Ctrl+F4
全局 全部保存 Ctrl+Shift+S
全局 全部关闭 Ctrl+Shift+F4
全局 属性 Alt+Enter
全局 新建 Ctrl+N

项目
作用域 功能 快捷键
全局 全部构建 Ctrl+B

源代码
作用域 功能 快捷键
java编辑器 格式化 Ctrl+Shift+F
java编辑器 取消注释 Ctrl+\
java编辑器 注释 Ctrl+/
java编辑器 添加导入 Ctrl+Shift+M
java编辑器 组织导入 Ctrl+Shift+O
java编辑器 使用try/catch块来包围 未设置,太常用了,所以在这里列出,建议自己设置。
也可以使用Ctrl+1自动修正。

运行
作用域 功能 快捷键
全局 单步返回 F7
全局 单步跳过 F6
全局 单步跳入 F5
全局 单步跳入选择 Ctrl+F5
全局 调试上次启动 F11
全局 继续 F8
全局 使用过滤器单步执行 Shift+F5
全局 添加/去除断点 Ctrl+Shift+B
全局 显示 Ctrl+D
全局 运行上次启动 Ctrl+F11
全局 运行至行 Ctrl+R
全局 执行 Ctrl+U

重构
作用域 功能 快捷键
全局 撤销重构 Alt+Shift+Z
全局 抽取方法 Alt+Shift+M
全局 抽取局部变量 Alt+Shift+L
全局 内联 Alt+Shift+I
全局 移动 Alt+Shift+V
全局 重命名 Alt+Shift+R
全局 重做 Alt+Shift+Y
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)
Ctrl+D: 删除当前行
Ctrl+Alt+↓ 复制当前行到下一行(复制增加)
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)
Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)
Alt+↑ 当前行和上面一行交互位置(同上)
Alt+← 前一个编辑的页面
Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)
Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性
Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)
Shift+Ctrl+Enter 在当前行插入空行(原理同上条)
Ctrl+Q 定位到最后编辑的地方
Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)
Ctrl+M 最大化当前的Edit或View (再按则反之)
Ctrl+/ 注释当前行,再按则取消注释
Ctrl+O 快速显示 OutLine
Ctrl+T 快速显示当前类的继承结构
Ctrl+W 关闭当前Editer
Ctrl+K 参照选中的Word快速定位到下一个
Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)
Ctrl+/(小键盘) 折叠当前类中的所有代码
Ctrl+×(小键盘) 展开当前类中的所有代码
Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用

Alt+/来代替)
Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)
Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没

有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)
Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)
Ctrl+Shift+F4 关闭所有打开的Editer
Ctrl+Shift+X 把当前选中的文本全部变味小写
Ctrl+Shift+Y 把当前选中的文本全部变为小写
Ctrl+Shift+F 格式化当前代码
Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反

之)
下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift

开头的了)
Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力

)
Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)
Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)
Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)
Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)
Alt+Shift+I 合并变量(可能这样说有点不妥Inline)
Alt+Shift+V 移动函数和变量(不怎么常用)
Alt+Shift+Z 重构的后悔药(Undo)
编辑
作用域 功能 快捷键
全局 查找并替换 Ctrl+F
文本编辑器 查找上一个 Ctrl+Shift+K
文本编辑器 查找下一个 Ctrl+K
全局 撤销 Ctrl+Z
全局 复制 Ctrl+C
全局 恢复上一个选择 Alt+Shift+↓
全局 剪切 Ctrl+X
全局 快速修正 Ctrl1+1
全局 内容辅助 Alt+/
全局 全部选中 Ctrl+A
全局 删除 Delete
全局 上下文信息 Alt+?
Alt+Shift+?
Ctrl+Shift+Space
java编辑器 显示工具提示描述 F2
java编辑器 选择封装元素 Alt+Shift+↑
java编辑器 选择上一个元素 Alt+Shift+←
java编辑器 选择下一个元素 Alt+Shift+→
文本编辑器 增量查找 Ctrl+J
文本编辑器 增量逆向查找 Ctrl+Shift+J
全局 粘贴 Ctrl+V
全局 重做 Ctrl+Y

查看
作用域 功能 快捷键
全局 放大 Ctrl+=
全局 缩小 Ctrl+-

窗口
作用域 功能 快捷键
全局 激活编辑器 F12
全局 切换编辑器 Ctrl+Shift+W
全局 上一个编辑器 Ctrl+Shift+F6
全局 上一个视图 Ctrl+Shift+F7
全局 上一个透视图 Ctrl+Shift+F8
全局 下一个编辑器 Ctrl+F6
全局 下一个视图 Ctrl+F7
全局 下一个透视图 Ctrl+F8
文本编辑器 显示标尺上下文菜单 Ctrl+W
全局 显示视图菜单 Ctrl+F10
全局 显示系统菜单 Alt+-

导航
作用域 功能 快捷键
java编辑器 打开结构 Ctrl+F3
全局 打开类型 Ctrl+Shift+T
全局 打开类型层次结构 F4
全局 打开声明 F3
全局 打开外部javadoc Shift+F2
全局 打开资源 Ctrl+Shift+R
全局 后退历史记录 Alt+←
全局 前进历史记录 Alt+→
全局 上一个 Ctrl+,
全局 下一个 Ctrl+.
java编辑器 显示大纲 Ctrl+O
全局 在层次结构中打开类型 Ctrl+Shift+H
全局 转至匹配的括号 Ctrl+Shift+P
全局 转至上一个编辑位置 Ctrl+Q
java编辑器 转至上一个成员 Ctrl+Shift+↑
java编辑器 转至下一个成员 Ctrl+Shift+↓
文本编辑器 转至行 Ctrl+L

搜索
作用域 功能 快捷键
全局 出现在文件中 Ctrl+Shift+U
全局 打开搜索对话框 Ctrl+H
全局 工作区中的声明 Ctrl+G
全局 工作区中的引用 Ctrl+Shift+G

文本编辑
作用域 功能 快捷键
文本编辑器 改写切换 Insert
文本编辑器 上滚行 Ctrl+↑
文本编辑器 下滚行 Ctrl+↓

文件
作用域 功能 快捷键
全局 保存 Ctrl+X
Ctrl+S
全局 打印 Ctrl+P
全局 关闭 Ctrl+F4
全局 全部保存 Ctrl+Shift+S
全局 全部关闭 Ctrl+Shift+F4
全局 属性 Alt+Enter
全局 新建 Ctrl+N

项目
作用域 功能 快捷键
全局 全部构建 Ctrl+B

源代码
作用域 功能 快捷键
java编辑器 格式化 Ctrl+Shift+F
java编辑器 取消注释 Ctrl+\
java编辑器 注释 Ctrl+/
java编辑器 添加导入 Ctrl+Shift+M
java编辑器 组织导入 Ctrl+Shift+O
java编辑器 使用try/catch块来包围 未设置,太常用了,所以在这里列出,建议自己设置。
也可以使用Ctrl+1自动修正。

运行
作用域 功能 快捷键
全局 单步返回 F7
全局 单步跳过 F6
全局 单步跳入 F5
全局 单步跳入选择 Ctrl+F5
全局 调试上次启动 F11
全局 继续 F8
全局 使用过滤器单步执行 Shift+F5
全局 添加/去除断点 Ctrl+Shift+B
全局 显示 Ctrl+D
全局 运行上次启动 Ctrl+F11
全局 运行至行 Ctrl+R
全局 执行 Ctrl+U

重构
作用域 功能 快捷键
全局 撤销重构 Alt+Shift+Z
全局 抽取方法 Alt+Shift+M
全局 抽取局部变量 Alt+Shift+L
全局 内联 Alt+Shift+I
全局 移动 Alt+Shift+V
全局 重命名 Alt+Shift+R
全局 重做 Alt+Shift+Y

[转载]程序员养生(01)心态

mikel阅读(686)

[转载]程序员养生(01) -- 心态 – zhuweisky – 博客园.

在程序之外,是程序员的生活。

当我们刚刚告别校园成为一个程序员时,大都拥有成功的梦想、万分的激情,那时的我们也拥有精力充沛的健康身体。 随时间流逝,5年过去了、10年过去了,也许,梦想可能渐渐暗淡,激情慢慢消退。但,有一点是肯定的,我们的身体大不如前了,像视力下降、慢性胃炎、颈椎 病、失眠、神经衰弱等等接踵而来,这些病症几乎成了我们这个行业的职业病。

从健康的角度来说,程序员这个职业,有几个非常不利的因素:

第一,程序员需要专注。程序员经常连续长时间地(例如连续8个小时以上,为解决一个bug,饭顾不上吃、睡觉也在想解决方案)专注在一个问题上,这对气血的消耗是非常巨大的。几年前华为一个员工因连续加班而导致过劳死,就是一个典型的例子。

第二,长时间静坐。长时间静坐,导致身体气血循环不畅、经常有某个部分涨痛的情况出现,这就提醒你要多运动运动了。而且,久坐伤胃,过度思虑也伤胃,所以很多程序员都有慢性胃炎这类疾病。

第三,脑力消耗巨大。靠出卖脑力养家活口的程序员,连续的脑力消耗、加上工作方面的精神压力巨大,久而久之,容易患上头痛、偏头痛等毛病。

第四,长时间面对电脑。虽说现在都用LCD显示器,辐射小一些,但是长时间专注地盯着屏幕,对视力的危害是非常大的。而且,久视伤肝,加上经常晚上熬夜加班,程序员就容易肝火旺、眼眶痛(特别是鱼腰穴处)、目赤等。

身体是自己的,是一辈子的事情。我向来不赞成为了事业,而牺牲健康。(还有,为了利益,而牺牲感情;为了金钱,而不择手段。)

想要健康的身体和健康的生活,心态是最重要的。而且,实际上,在诸多的因素中,心态对身体健康的影响是最大的。中医早在几千年前就深刻地认识到了这一点,长期的沉侵在过度的七情(怒喜忧惊悲思恐)之中,对身体的损害相当之大。就正如久郁成疾一样。

随着年纪的增长,心态会慢慢发生变化。以前觉得很重要的,像金钱、名利、地位,慢慢地发现它不是那么重要;以前不以为然的,像亲情、友情,却觉得越来越珍贵。

今天,已而立之年。就像大多数人一样,不太成功,也不太失败。平淡真实地过着每一天,也许这就是一种幸福的状态的吧。下面就罗列一些我自以为是的观点,仅供大家参考。

(1)不强求、顺其自然。不强求于人,不要让别人难做;也不要强求于事,谋事在人、成事在天。

我们很多痛苦的根源在于,我们太执着了,太强求了。即使有雄心壮志,要做一番大事业,也该是尽人事,听天命。这不是宿命论,而是诸多事情,人算不如天算,塞翁失马焉知非福呢?

(2)掌握事物的规律,抓住关键点,就不用紧张、焦虑,而且往往事半功倍。

比如,我们没有必要不等春天的到来而焦急地在冬天的时候去播种(而现实中,我们为了急于求成,常常在不合时机的时候做不适合的事),因为这违反了自然界的 规律,付出一定没有回报。反过来,你也不能因一时懒惰而错过了春天播种、秋天收获的时节,否则,因一时情绪之快,你就要多等一年了。

很多事情,看似无为,实则大为。正像老子说的,无为而无不为。

(3)勤动脑体,不动心。

正常的工作、生活是没问题的(即勤动脑体),但是不要动心。“动心”的意思是说,一件事情,你放不下,吃饭的时候也想、睡觉的时候也想,时时刻刻挂在心上,这就是动心了。动心会使气郁,会伤身。

(4)要放得下、要看得开、要放得开。知足常乐。

放得下是魄力、看的开是胸襟、放得开是气度。知足则是最大的精神财富。

(5)失意时要坚韧,得意时要低调。

人生在世,难免有得有失,难免有低潮和春风得意之时。就像,舍得舍得,舍去之后便是得;而得失得失,跟在得后面的就是失。了解这一点,无论是在低潮还是在高潮,我们的情绪都不会太激烈。平淡一点、活得从容。

路是我们自己选的,拥有一种良好的心态,其实,生活就在我们自己的手中。

[转载]如何将List转换相应的Html(xsl动态转换)(一)

mikel阅读(1030)

[转载]如何将List转换相应的Html(xsl动态转换)(一) – JasenKin – 博客园.

一、前言

根据指定的xsl样式将List<T>转换相应的Html,其中涉及到怎样将List<T>转换成DataTable,如何将xml文本、xsl样式文本动态转换成html以及如何设置以及控制xsl样式。主要步骤如下:

步骤一、将List<T>转换成DataTable。

步骤二、将Xml与Xsl动态转换成Html。

步骤三、设置以及控制Xsl的内容样式。

以上的三个步骤本人将以此顺序介绍相关的内容,分别对应相关的随笔,因为本人上班的时候不能上网以及时间上的问题,所以才将该文章分3次来写。

二、类图设计

以上的内容涉及的类图虽然很简单,但是本人还是花了不少时间的来实现具体功能,代码质量还是可以保证的。EntityMapper负责将 List<T>转换成DataTable(目前先将就着用这个,还有一个比较复杂的,涉及的东西比较多,此处不会讲解,以后有时间再 写),XslTransform负责将xml文本、xsl文本转换成html,XslTransformFacade外观模式封装其中的细节,如下:

三、将List<T>转换成DataTable,再转换成xml的具体实现

这里主要是个思路的问题,先将List<T>转换成DataTable,然后将DataTable添加到DataSet中,最后通过 DataSet的GetXml()方法获取Xml内容。这里思路正确的话,实现不是很复杂。先看下XslTransformFacade类,基本思路都封 装在该类中:

public class XslTransformFacade
{
public static string ToHtml(List entities,string xslText) where T : new()
{
if (ValidateArgs(entities,xslText))
{
return string.Empty;
}

string xmlText= GetXmlText(entities);

using (XslTransform xslTransform = new XslTransform())
{
return xslTransform.Transfer(xmlText, xslText);
}
}

private static bool ValidateArgs(List entities, string xslText)
{
return entities == null || entities.Count == 0
|| string.IsNullOrWhiteSpace(xslText);
}

private static string GetXmlText(List entities) where T : new()
{
using (DataSet dataSet = new DataSet("DataSet"))
{
DataTable dataTable = EntityMapper.ToDataTable(entities);
dataSet.Tables.Add(dataTable);
return dataSet.GetXml();
}
}
}

这一步骤主要是通过GetXmlText(List entities)方法来实现的。EntityMapper.ToDataTable(entities)方法将在下面介绍。生成的Xml如下(示例):

-
-
MapperInfoIndex0
2011-05-24T00:27:23.734375+08:00
true
0

0   www.codeplex.com?Id=0

-
MapperInfoIndex1
2011-05-24T00:27:23.734375+08:00
false
1
www.codeplex.com?Id=1

-

其次第12-15行主要是将xmlText、xslText转换成html,这将在后续的文章中介绍具体实现:

using (XslTransform xslTransform = new XslTransform())
{
return xslTransform.Transfer(xmlText, xslText);
}

四、将List<T>转换成DataTable

这里主要是通过反射将List<T>转换成DataTable。其中需要设置DataTable的DataColumnCollection集合以及设置DataRowCollection集合。具体代码如下:

public sealed class EntityMapper
{
public static DataTable ToDataTable(List entities) where T : new()
{
if (entities == null || entities.Count == 0)
{
return new DataTable();
}

using (DataTable dataTable = new DataTable(typeof(T).Name))
{
PropertyInfo[] properties = typeof(T).GetProperties();

SetColumnsType(properties, dataTable);
SetTableContent(entities, properties, dataTable);

return dataTable;
}
}

private static void SetTableContent(List entities,
PropertyInfo[] properties, DataTable dataTable)
{
foreach (T entity in entities)
{
AddTableRowsAndContent(properties, entity,dataTable);
}
}

private static void AddTableRowsAndContent(PropertyInfo[] properties,
T entity, DataTable dataTable)
{
DataRow newRow = dataTable.NewRow();
foreach (PropertyInfo propertyInfo in properties)
{
if (!CanGetPropertyValue(propertyInfo,dataTable))
{
continue;
}

try
{
object objValue = propertyInfo.GetValue(entity, null);
newRow[propertyInfo.Name] = objValue ?? DBNull.Value;
}
finally
{
}
}

dataTable.Rows.Add(newRow);
}

private static bool CanGetPropertyValue(PropertyInfo propertyInfo, DataTable dataTable)
{
return propertyInfo.CanRead &amp;&amp;
dataTable.Columns.Contains(propertyInfo.Name);
}

private static void SetColumnsType(PropertyInfo[] properties, DataTable dataTable)
{
Type colType = null;

foreach (PropertyInfo propInfo in properties)
{
if (propInfo.PropertyType.IsGenericType)
{
colType = Nullable.GetUnderlyingType(propInfo.PropertyType);
}
else
{
colType = propInfo.PropertyType;
}

if (colType.FullName.StartsWith("System"))
{
dataTable.Columns.Add(propInfo.Name, colType);
}
}
}
}

这里主要的操作步骤为以下2行代码:

14 SetColumnsType(properties, dataTable);
15 SetTableContent(entities, properties, dataTable);

14行设置列的类型,15行设置DataRowCollection的DataRow内容,对于上面的代码,再多的解释都是无用的,看具体代码就行了。

其中需要解释一下的就是54-58行:

54 private static bool CanGetPropertyValue(PropertyInfo propertyInfo, DataTable dataTable)
55 {
56 return propertyInfo.CanRead &&
57 dataTable.Columns.Contains(propertyInfo.Name);
58 }
因为当属性不可读,并且DataColumnCollection不包行该属性名时,赋值可能会抛出异常的。

其次还提一下第10行:

10 using (DataTable dataTable = new DataTable(typeof(T).Name))

这里用using来释放资源,主要是使代码中不存在任何警告,警告有时候使系统奔溃也有可能。否则进行代码分析的时候会出现警告信息,如下图所示:

五、DataTable 转换成List<T> (这个是附加的,与此主题无关,但是也是EntityMapper 的一部分)

虽然以前写了一篇《 将DataRow转换成相应的对象(通用以及泛型操作) 》 ,但是并不是将DataTable 转换成List<T>,后续也有些地方进行了改进,代码如下:

public class EntityMapperTest
{
[TestMethod()]
public void ToDataTableTest()
{
List entities = CreateMapperInfos(9);
DataTable result = EntityMapper.ToDataTable(entities);
Assert.IsNotNull(result);
Assert.IsNotNull(result.Rows);
Assert.AreEqual(9, result.Rows.Count);
int index = 0;
foreach (DataRow dataRow in result.Rows)
{
Assert.AreEqual(dataRow[“Name”],
string.Concat(“MapperInfoIndex”, index.ToString()));
Assert.AreEqual(dataRow[“IsActive”], index % 2 == 0 ? true : false);
Assert.AreEqual(dataRow[“Value”], index);
Assert.IsNotNull(dataRow[“CreatedTime”]);
Assert.AreEqual(dataRow[“Percent”], DBNull.Value);
index++;

}
}

private List CreateMapperInfos(int count)
{
List entities = new List();
for (int index = 0; index < count; index++) { entities.Add(new MapperInfo() { Name = string.Concat("MapperInfoIndex", index.ToString()), IsActive = (index % 2 == 0 ? true : false), CreatedTime = DateTime.Now, Value = index }); } return entities; } } [/csharp] 七、总结 最近二个多月,忙死我了。这段时间转SIT测试了,终于又可以轻松一阵了,哈哈。这些随笔的内容都是上班时间之外写的,每次写的代码都做单元测试,主要是避免出现显而易见的BUG,以及将代码积累并且更新到自己的框架中。接下来的一篇主要是如何将xml文本、xsl文本动态转换成html,这个花费了本人一段时间,一直在摸索才整理出来的,主要是通过XslCompiledTransform.Transform(XmlReader input, XmlWriter results)来实现的,本人已经更新了几个版本了,这个应该是最终版本的,同时也是最精简的版本。

[转载]Android获取已安装应用信息(图标,名称,版本号,包)

mikel阅读(896)

[转载]Android获取已安装应用信息(图标,名称,版本号,包) – MainRoad – 博客园.

Android 菜市场上有一款应用较 ShareApp,可以显示,管理,分享Android手机上安装的应用。

但比较不爽的是,它把很多系统自带的应用程序也都显示了出来。这些程序往往是无法卸载的,更无法分享,让“已安装应用程序”的列表显的非常凌乱。

我在手机上运行了一下,结果Gtalk,DRMService这些系统应用都显示出来了..比较不爽。

于是自己写了个程序,看看能不能只显示用户自己安装的程序。

程序大概分成三个部分:

1.获取手机已安装的所有应用package的信息(其中包括用户自己安装的,还有系统自带的);

2.滤除系统自带应用;

3.通过列表显示出应用程序的图标(icon),和其他文字信息(应用名称,包名称package name,版本号等等)

首先,我们定义一个数据结构,来保存应用程序信息(icon,name,packageName,versionName,versionCode,等)

public class AppInfo {
public String appName="";
public String packageName="";
public String versionName="";
public int versionCode=0;
public Drawable appIcon=null;
public void print()
{
Log.v("app","Name:"+appName+" Package:"+packageName);
Log.v("app","Name:"+appName+" versionName:"+versionName);
Log.v("app","Name:"+appName+" versionCode:"+versionCode);
}

}

然后我们通过PackageManager 来获取已安装的应用包信息。

ArrayList appList = new ArrayList(); //用来存储获取的应用信息数据
List
packages = getPackageManager().getInstalledPackages(0);

for(int i=0;i
PackageInfo packageInfo = packages.get(i);
AppInfo tmpInfo = new AppInfo();
tmpInfo.appName = packageInfo.applicationInfo.loadLabel(getPackageManager()).toString();
tmpInfo.packageName = packageInfo.packageName;
tmpInfo.versionName = packageInfo.versionName;
tmpInfo.versionCode = packageInfo.versionCode;
tmpInfo.appIcon = packageInfo.applicationInfo.loadIcon(getPackageManager());
appList.add(tmpInfo);

}
//好啦 这下手机上安装的应用数据都存在appList里了。

那么如何判断一个应用是否为系统应用呢?

if((packageInfo.applicationInfo.flags&amp;ApplicationInfo.FLAG_SYSTEM)==0)
{
//非系统应用
}
else
{
//系统应用
}

所以如果只需要获取到非系统应用信息,代码如下:

ArrayList appList = new ArrayList(); //用来存储获取的应用信息数据
List
packages = getPackageManager().getInstalledPackages(0);

for(int i=0;i PackageInfo packageInfo = packages.get(i);
AppInfo tmpInfo = new AppInfo();
tmpInfo.appName = packageInfo.applicationInfo.loadLabel(getPackageManager()).toString();
tmpInfo.packageName = packageInfo.packageName;
tmpInfo.versionName = packageInfo.versionName;
tmpInfo.versionCode = packageInfo.versionCode;
tmpInfo.appIcon = packageInfo.applicationInfo.loadIcon(getPackageManager());
//Only display the non-system app info
if((packageInfo.applicationInfo.flags&amp;ApplicationInfo.FLAG_SYSTEM)==0)
{
appList.add(tmpInfo);//如果非系统应用,则添加至appList
}

}

最后,我们可以自定义一个app_row.xml的layout 文件,用来显示appList中的数据

是不是看着利索多了~~~(我在每行里只显示了icon 和 appName,你也可以修改app_row.xml 和 AppAdapter 部分后显示更多的信息)

大家可以参考我的源码:

源码下载地址:
http://www.everbox.com/f/cV98GFipIUHV34WOmXNdemQ6Vm

我的联系方式:

twitter: @mainroadlee

talkbox id:mainroadlee


参考:

1. [Android分享] Android 得到已安装的应用程序信息

http://www.eoeandroid.com/thread-67948-1-1.html

该文中描述了如何获取Android 已安装应用信息,但关于系统应用的判断部分存在错误。

2. Android中级篇之区分系统程序和安装程序

http://blog.csdn.net/y13872888163/archive/2011/05/20/6435618.aspx

[转载]Android Market排名算法及规则

mikel阅读(809)

[转载]Android Market排名算法及规则 – deaboway – 博客园.

(Just one blogger _guess_ how Google rates apps on Android market. For reference only)

http://www.mobile20.com.cn/android-market-ranking-rules/

众所周知,做搜索出身的Google,旗下的Market的排名肯定是依据一个形同( A×a% + B×b% + C×c%)的公式计算出来的数值,进行排名的。开发者可根据其排名规则,对自己的产品设计和研发以及推广进行指导。

1. 排名公式里有哪些指标?

指标A、B、C到底是什么?权重a、b、c究竟是多少?这些问题的答案,应该是每个App开发者和运营者都渴望了解的。知道了这个答案之后,有些“聪 明”的人就会像当年SP的从业者一样,去刷那些权重大的指标、从而拉升产品的排名了。网上关于此问题的讨论很多都是不了了之、无疾而终。相对较深入的一篇 文章《Android Market App Rankings》,也只是在猜想是基于“安装量”的增长和留存。可惜,该作者离正确答案就差一步了……

也 许你已经等得不耐烦了,哈哈。现在就说说我的结论吧。指标A=“总安装/总下载”,即下载转安装的转换率;B=“评分/5”,即产品得分比上Market 的满分;C=“留存安装/总安装”,即安装的留存率。不要急着问我a、b、c等于多少,准确数值只有Google知道、而且可以调,我只能告诉你它们加起 来等于100,还有就是b>max(a,c)(为什么?下面耐心看)。

依据这个推断公式,就是说如果每个下载的用户都安装了、而且都给了5分、并且一直都没有卸载——OK.不论a、b、c是多少,你的产品得了满分,它就是No.1!

2. 为什么是它们?

在告诉你为什么是A、B、C之前,我先告诉你为什么不是D、E、F……

先看个数据,Android Market-通信-免费-TOP25:

去掉了产品名称,我们可以看到更纯的数据。

首先,我 们可以肯定的排除排名是按“下载次数”排序的,下载次数1万+的产品(第9位)居然排到了下载次数500万+(第11位)的前面。试想第11位的产品在 喊:“这是为什么?它哪点比我好???”——答案:请看“评分”。啊?它是5分!没错,第9位的产品评分得了满分。哦,排除了D的同时,我们收获了B。

其次,我们可以排除“评分人数”。原因就是,在“下载次数”和“评分”都同等量级的情况下,比对了若干样本,都无章可循——实在跟“评分人数”不相干。E被干掉了。

再次,要 排除的是“加速度”。很多人在猜测会有一个“加速度”指标,或者新增下载的、或是新增安装的。大家的这种猜测是源自于“鼓励新产品”,但是这是一种过于激 进的想法。Market这么大盘子是要鼓励推陈出新的,但“保护”新产品的同时也得“爱护”那些确实有实力的老产品。过大的用户基数,肯定会拖慢老牛产品 的“加速度”,如果这么做的话每天的TOP10都是面目全非的(App Store的排名规则里就有“加速度”,所以TOP榜天天易容)。所以,“加速度”也不是真正的公平。

排除了D、E、F,收获了B。那A和C是从哪来的?

休息一下,问个题外话?我们一般是怎么评判一个物品的“好”“坏”的?是不是有以下部分组成?有一样东西摆在你面前,勾起了你试用的欲望。试用之后,你 可能爱不释手,继续用吧。路遥知马力,又用了一段时间,你又有了新的评判。如果这个东西实在是太好了,那你就会与它形影不离……回归到我们判断一个物品的 标准的本质,无非就是是否“接受它”、是否“肯定它”、是否“留着它”。

言 归正传,用户是否“接受”一个App——下载只是“抬头”,安装才是“点头”。如果单以“安装”为指标,又会让老产品滚雪球,有失公平。所以,A(下载转 安装的转化率)浮出水面了。“安装”做分母,“下载”做分子。一方面,排名在前的产品下载量越高、安装量就有可能越高的同时,如果产品不够好“下载量”越 高就可能成了拖后腿的那个分母,上面举例的第11位产品就是个例子(庞大的下载量下,安装量无法保持同步增长,所以让其难堪重负,排名下落——剧透下,第 11位是曾经“通信”下排名第1的产品KakaoTalk)。另一方面,只要A(还有B、C)足够好,也让一些新产品可以冒出头来。

B(评分)刚才已经分析到了,这里需要补充一点的是:评分不是一次性的。我们会发现在Market里“评分”是可以多次修改的,这样的目的就是鞭策产品 要持续的“好”,用户一直掌握着产品的“生杀大权”。另外,就是为什么前文说到b大于a和c,原因就是纵观TOP100,评分低于4分的只有两 个;TOP25,评分低于4的是零个;TOP10,评分低于4.5的只有一个(避免出现App Store里《小姐日记》这样低分却长期占据高排位的现象)——一言以蔽之:要想在前排就坐,产品首先得让用户觉得“好”。

该说说C(安装留存率)的出处。说白了就是控制流失率,如果“总安装”很高、但是“留存安装”很少,那也不能称之为“好”产品。所以,安装留存率就是另一个全面衡量产品优劣的指标。

3. 它们到底是多少?

前文已经说到b比a和c都大,那a和c孰大孰小呢?这个取决于Android Market的策略,如果“a比c大”意味着“更看重新增”(任何一个店铺先开张的时候,都会最看重这个)、如果“c比a大”意味着“更看重留存”(对于 一个已经把客流吃透的老店,会更看重这个)——所以,这个真是可以调的,取决于Android Market发展到哪个阶段和运营管理者的自我认识。

4. 感言

Android Market如果真是我想象的这样排名,可谓新老兼顾,攻防兼备。

说它新老兼顾,是因为它让新鲜的好的新产品既能快速冒出来、也能让它经得起时间的推敲,或昙花一现或源远流长。说它攻守兼备,是因为这样会把盘子越做越 大,而且也防止了“刷”(能刷上去,但是刷上去之后如果产品不够好,会让产品跌得更惨),把盘子越做越牢。这样公平的规则,也为Android Market的应用量新增速度已超过App Store提供了另一个有力的支持。高!实在是高!

Android Market排名规则这个隐形的裁判告诉我们:持续地把产品做好,才是正道!

[转载]ASP.NET MVC在IIS6下部署的小技巧

mikel阅读(782)

[转载]ASP.NET MVC在IIS6下部署的小技巧 – P_Chou – 博客园.

通常在IIS6下部署ASP.NET MVC应用程序的时候,都是直接设置把所有请求都交由ASP.NET的ISAPI处理。MVC是基于ASP.NET的,框架默认对于任何请求都会优先检查物理路径是否存在物理文件,如果存在的话就不通过MVC的路由机制,否则才走路由。因此,如果在不考虑控制静态资源权限的情况下,可以设置静态资源不通过ASP.NET的ISAPI,而直接由IIS处理,通过这种方式提升一些性能。本文围绕这个主题,详解部署过程。


0.在设计MVC网站的时候,把静态资源统一放在一个文件夹下,建议目录结构使用小写字母

1.把web应用程序发布到某个路径下(略)(顺便提一句,MVC2功能上比MVC3弱一些,用到的组件很少,可以直接私有部署System.Web.Mvc;但是MVC3因为功能增加,而且引入了Razor引擎,依赖的组件增多,建议在部署的时候直接安装MVC3)

2.创建一个web站点(略)

3.右击创建的web站点,选择属性,切换到Home Directory页

clip_image001

4.点击Configuration,在Wildcard application maps中,点击Insert,添加C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll,取消Verify that file existsg的勾选。(如果使用MVC2的话,可以到2.0下去找这个dll。这里去掉对静态文件的验证是关键,这使得asp.net处理所有的请求)

clip_image001

5.点OK

clip_image001[6]

6.允许ASP.NET 4.0扩展

clip_image002

7.content目录是静态资源放置的目录,设置content目录下请求直接由IIS处理以提高性能。右击content,属性

clip_image001[6]

8.点击create,再点击configuration,移除Wildcard application maps下的内容。点击OK。这里利用了IIS的一个bug,把目录设置成虚拟目录,删除Wildcard application maps的设置,这样这个虚拟目录的请求就直接由IIS处理了。

clip_image001[8]

9. 再点击Remove,把虚拟目录恢复成普通目录。这样只有这个目录下的文件会受到IIS的“眷顾”

clip_image001[10]

10.设置AppPool权限。点击站点使用的AppPool的属性,切换到Identity,选择Local System。这是偷懒的设置方法,以避免出现应用程序本身对系统的访问权限不够

clip_image001[14]

11.设置匿名访问权限。右击站点,选择权限。点击Add…,在弹出的对话框中输入IUSR_XXX(XXX为机器名)。

clip_image001[16]

点击OK,便可添加一个Internet Guest Account,保持默认的只读权限即可。

clip_image001[18]

12.最后注意,如果是首次安装.NET 4.0,不要忘了注册

clip_image001[12]

深入理解ASP.NET MVC(2)中,讨论过MVC框架的路由机制,其中提到“可以通过设置RouteCollection的RouteExistingFilestrue,使得路由不匹配静态文件(注意true是不匹配,这个命名和奇怪)。”因此,我们可以这样设置,以使得MVC不对静态文件进行检查,这样又可以提高一点性能。最终请求会像下图那样被serve

image

[转载]用C#编写一个抓网页的应用程序

mikel阅读(927)

[转载]用C#编写一个抓网页的应用程序 – 临河羡鱼 – 博客园.

C#.NET提供的类来轻松创建一个抓取网页内容源代码的程序 。HTTPWWW进行数据访问最基本的协议之一,在.NET的基本类型库类中提供了两个对象类:HTTPWebRequestHTTPWebResponse,分别用来向某资源发送请求和获得响应。为了得到一个资源的内容,我们先指定一个想要抓取的URL地址,用HTTPWebRequest对象进行请求,用HTTPWebResponse对象接收响应的结果,最后用TextStream对象来提取我们想要的信息,并在控制台打印出来。
下面就是看看如何实现这样的功能:

第一步:打开VS.NET,点文件”-“新建”-“项目,项目类型选择“Visual C#项目,模板选“Windows应用程序
第二步:在Form1里加入Label1Button1,TextBox1,TextBox2四个控件,TextBox2Multiline属性改为True,
第三步:在Form1窗体上点击右键,选查看代码,button1的Click事件代码:

using System.IO;
using System.Net;
using System.Text;
private void button1_Click(object sender,
System.EventArgs e)
{
byte[] buf = new byte[38192];
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(textBox1.Text);
HttpWebResponse response = (HttpWebResponse)
request.GetResponse();
Stream resStream = response.GetResponseStream();
int count = resStream.Read(buf, 0, buf.Length);
textBox2.Text = Encoding.Default.GetString(buf, 0,
count);
resStream.Close();

}

第四步:点“Save all”按钮,按“F5”运行应用程序,在请输入URL地址:后面的单行文本框里输入http://www.cnblogs.com/atun/archive/2011/05/22/2053847.htmlhttp://lucky.myrice.com/down.htm,点击得到 HTML 代码按钮,就可以看到该地址的代码了!

下面,我们就对上面的程序做一个分析:

上面的这个程序的功能是抓取网页http://lucky.myrice.com/down.htm的内容,并在多行文本框里显示出HTML代码,由于返回的数据是字节类型的,因此,我们创建一个名为buf的字节类型的数组变量来存储请求返回来的结果,其中数组的大小与我们要请求返回的数据大小有关系。首先,我们实例化HttpWebRequest对象,使用WebRequest类的静态方法Create(),该方法的字符串参数就是我们要请求页面的URL地址,由于Create()方法返回的是WebRequest类型的,我们必须对它进行造型(即类型转换)成HttpWebRequest类型,再赋给request变量。一旦我们建立了HttpWebRequest对象,就可以使用它的GetResponse()方法来返回一个WebResponse对象,然后再造型成HttpWebResponse对象赋给response变量。现在,就可以使用response对象的
GetResponseStream()方法来得到响应的文本流了,最后用Stream对象的Read()方法把返回的响应信息放到我们最初创建的字节数组buf中,Read()3个参数,分别是:要放入的字节数组,字节数组的开始位置,字节数组的长度。最后把字节转换成字符串,注意:这里采用的采用的是Default编码,它使用默认的编码方式,我们就不用再进行字符编码之间的转换了。也可以利用WebRequestWebResponse实现以上的功能,代码如下:

WebRequest request = WebRequest.Create(textBox1.Text);
WebResponse response =request.GetResponse();

输入其它的URL看看是不是很方便!