月份: 2014-01

@OneToMany 基于注解的单向关联

以前都一直用hbm.xml 来配关联关系,最近在项目里试着用注解 @OneToMany 用着,发现多了一张中间表。
于是发现,不加任何注解参数里,@OneToMany会自动建一张中间表。
 
遂加入 mappedBy 参数。发现save 的时候没存进去。
然后发现,mappedBy是被动维护方的配置,相当于 reverse=”true”
http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e1591
主动方使用的是 @JoinColumn
 
 

  @OneToMany
  @JoinColumn(name="articleId")
  private Set<Attach> attachs = new LinkedHashSet<Attach>();

jQuery.getJSON 跨域问题

jQuery的 getJSON 方法可以本地或远程获取JSON 对象进行操作。
其基本格式是:
jQuery.getJSON(url,data,success(data,status,xhr))
在不跨域的情况下:只需要

$.getJSON("http://localhost/getBookInfo/100",{},
  function(data){ $.each(data, function(k,v){
      $("#bookinfo_" + k.replace(/\./g, '\\.') ).html(v)})
})

但是如果是跨域的,则需要加入参数 callback=?

$.getJSON("http://remotehost/getBookInfo/100?callback=?",{},
   function(data){ $.each(data, function(k,v){
      $("#bookinfo_" + k.replace(/\./g, '\\.') ).html(v)})
})

而服务器端需要将 data 包装一下后返回,
如原返回是 { “name” : “bookname”, “price”:”50.00″ , “sold”:”150″ }
则包装后为 request.getParam(“callback”)({ “name” : “bookname”, “price”:”50.00″ , “sold”:”150″ }
跨域时,jQuery 会自动生成一个script标签加载 远程服务器上的 JS,而 script 标签本身是可以跨域的。在script 外面包上执行某个方法,方法名由 callback 传入,则 jQuery 会自动定义一个名称类似jQuery16209379892267785707_1363072523219的方法,再将这个名称以 callback 的参数传至服务器。即
http://remotehost/getBookInfo/100?callback=jQuery16209379892267785707_1363072523219
服务器则需要将原有的 data 外加
jQuery16209379892267785707_1363072523219({ “name” : “bookname”, “price”:”50.00″ , “sold”:”150″ })
加载完该JS 后,浏览器便会执行该JS,从而实现远程的 json 调用。
说白了还是 script 标签 + 一个特定的参数,只是写法统一得像 ajax 请求而已。

Tomcat 内存设置

set JAVA_OPTS=-Xms128m -Xmx1532m -XX:PermSize=128M -XX:MaxPermSize=1024m
加到 catalina.bat 或 sh里

自用的Java 工具类

public class MyFunction {
static final int DOT_COUNT = 3;
public static String rep(String str)
{
return str.replace("&lt;", "&amp;lt;").replace("&gt;", "&amp;gt;").replace("\"", "&amp;quot;");
}
public static String truncate(String str, int len) {
if (str.length() &lt;= len)
return rep(str);
int doubleLen = len * 2;
int passedChar = 0;
int i;
for(i=0; i&lt;str.length()&amp;&amp; passedChar&lt;doubleLen ; i++)
{
if(str.substring(i,   i+1).matches("[\\u4e00-\\u9fa5]+"))
passedChar = passedChar + 2;
else
passedChar++;
}
String short_str = str.substring(0, i);
if(i==str.length())
return rep(str);
return rep(short_str) + "...";
}
public static String encodeUrl(String url) {
String newUrl = url.replaceAll("\\?", "%3F").replaceAll("\\&amp;", "%26");
return newUrl;
}
public static String uriEncoding(String param) {
try {
param = new String(param.getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return param;
}
/**
* 判断对象是否为指定类的实例
*
* @param obj
* @param str
* @return
*/
public static boolean isInstance(Object obj, String str) {
try {
Class clazz = Class.forName(str);
boolean result = clazz.isInstance(obj);
return result;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
}
}
public static boolean isInstance2(Object obj, String str) {
String className = obj.toString();
className = className.substring(0, className.indexOf('@'));
boolean result = str.equals(className);
return result;
}
public static void main(String[] args) {
System.out.println(truncate(
"fdsf——33《》有+?、要@!#¥", 9));
}
}

Joda-time 果然秒杀 Calendar

能够和 JDK 的 Date , Calendar 无缝转换。
Month 的开始,一月的int 值不是可恶的 0,
爽快如 JQuery 般的链式调用

dateTime.plusDays(35).plusMonths(1).dayOfWeek().withMaximumValue().toString("E MM/dd/yyyy HH:mm:ss.SSS")

不用没事 new 一个 SimpleDateFormat 对象并调用它的format 方法。这本来就是 DateTime 相关类该做的事。
 
So cooooooooooool

转载:理解delete

在javascript中,我们有时候要使用delete删除对象。但是,对于delete的一些细节我们未必尽知。昨天,看到kangax分析delete的文章,获益匪浅。本文将文章的精华部分翻译出来,与各位分享。

  1. 原理
  2. Firebug 困惑
  3. 浏览器兼容性
  4. IE bugs
  5. 误区
  6. ‘delete’和宿主对象
  7. ES5严格模式
  8. 总结

原理

为什么我们能删除一个对象的属性?

var o = { x: 1 };
delete o.x; // true
o.x; // undefined

但是,像这样声明的变量则不行:

var x = 1;
delete x; // false
x; // 1

或者如此声明的函数:

function x(){}
delete x; // false
typeof x; // "function"

注意,当一个属性不能被删除时,delete只返回false。
要理解这一点,我们首先需要掌握像变量实例化和属性特性这样的概念--遗憾的是这些在关于javascript的书中很少讲到。我将在接下来的几个段落中试着简明的重温这些概念。 理解它们一点也不难,如果你不在乎它们为什么这么运行,你可以随意的跳过这一章。

代码类型

 
在ECMAScript中有三种类型的可执行代码:全局代码(Global code)函数代码(Function code)Eval code。这些类型有那么点自我描述,但这里还是作一个简短的概述:

  1. 当一段源代码正文被视为程序时,它在全局作用域中执行,被当成全局代码(Global code)。在一个浏览器环境中,SCRIPT元素中的内容通常被当作程序来解析,因此,它被当作全局代码来评估。
  2. 在一个函数内部直接执行的任何代码,很明显被当作函数代码(Function code)。在浏览器中事件属性的内容(如: <p onclick=”…”>)通常被当作函数代码(Function code)来解析;
  3. 最后,提供给内置函数eval()的文本被当作Eval 代码(Eval code)来解析。我们很快会看到这种类型很特殊。

执行上下文

当ECMAScript 代码执行时,它总是在一定的上下文中运行,执行上下文是一个有点抽象的实体,它有助于我们理解作用域和变量实例化如何工作的。对于三种类型的可执行代码, 每个都有执行的上下文。当一个函数执行时,可以说控制进入到函数代码(Function code)的执行上下文。全局代码执行时,进入到全局代码(Global code)的执行上下文。
正如你所见,执行上下文逻辑上来自一个栈。首先可能是有自己作用域的全局代码,代码中可能调用一个函数,它有自己的作用域,函数可以调用另外一个函数,等等。即使函数递归地调用它自身,每一次调用都进入一个新的执行上下文。

激活对象/变量对象

每一个执行上下文在其内部都有一个所谓的变量对象。与执行上下文类似,变量对象是一个抽象的实体,一个描述变量示例化的机制。现在,最有趣的是在源代码中声明的变量和函数被当作这个变量对象的属性被添加。
当控制进入全局代码的执行上下文时,一个全局对象用作变量对象。这也正是为什么在全局范围中声明的变量或者函数变成了全局对象的属性。

/* remember that `this` refers to global object when in global scope */
  var GLOBAL_OBJECT = this;
  var foo = 1;
  GLOBAL_OBJECT.foo; // 1
  foo === GLOBAL_OBJECT.foo; // true
  function bar(){}
  typeof GLOBAL_OBJECT.bar; // "function"
  GLOBAL_OBJECT.bar === bar; // true

Ok,全局变量变成了全局对象的属性,但是,那些在函数代码(Function code)中定义的局部变量又会如何呢?行为其实很相似:它成了变量对象的属性。唯一的差别在于在函数代码(Function code)中,变量对象不是全局对象,而是所谓的激活对象。每次函数代码(Function code)进入执行作用域时,激活对象即被创建。
不仅函数代码(Function code)中的变量和函数成为激活对象的属性,而且函数的每一个参数(与形参相对应的名称)和一个特定Arguments 对象(Arguments )也是。注意,激活对象是一种内部机制,不会被程序代码真正访问到。

  (function(foo){
    var bar = 2;
    function baz(){}
    /*
    In abstract terms,
    Special `arguments` object becomes a property of containing function's Activation object:
      ACTIVATION_OBJECT.arguments; // Arguments object
    ...as well as argument `foo`:
      ACTIVATION_OBJECT.foo; // 1
    ...as well as variable `bar`:
      ACTIVATION_OBJECT.bar; // 2
    ...as well as function declared locally:
      typeof ACTIVATION_OBJECT.baz; // "function"
    */
  })(1);

最后,在Eval 代码(Eval code)中声明的变量作为正在调用的上下文的变量对象的属性被创建。Eval 代码(Eval code)只使用它正在被调用的哪个执行上下文的变量对象。

  var GLOBAL_OBJECT = this;
  /* `foo` is created as a property of calling context Variable object,
      which in this case is a Global object */
  eval('var foo = 1;');
  GLOBAL_OBJECT.foo; // 1
  (function(){
    /* `bar` is created as a property of calling context Variable object,
      which in this case is an Activation object of containing function */
    eval('var bar = 1;');
    /*
      In abstract terms,
      ACTIVATION_OBJECT.bar; // 1
    */
  })();

属性特性

现在变量会怎样已经很清楚(它们成为属性),剩下唯一的需要理解的概念是属性特性。每个属性都有来自下列一组属性中的零个或多个特性--ReadOnly, DontEnum, DontDeleteInternal,你可以认为它们是一个标记,一个属性可有可无的特性。为了今天讨论的目的,我们只关心DontDelete 特性。
当声明的变量和函数成为一个变量对象的属性时--要么是激活对象(Function code),要么是全局对象(Global code),这些创建的属性带有DontDelete 特性。但是,任何明确的(或隐含的)创建的属性不具有DontDelete 特性。这就是我们为什么一些属性能删除,一些不能。

var GLOBAL_OBJECT = this;
  /*  `foo` is a property of a Global object.
      It is created via variable declaration and so has DontDelete attribute.
      This is why it can not be deleted. */
  var foo = 1;
  delete foo; // false
  typeof foo; // "number"
  /*  `bar` is a property of a Global object.
      It is created via function declaration and so has DontDelete attribute.
      This is why it can not be deleted either. */
  function bar(){}
  delete bar; // false
  typeof bar; // "function"
  /*  `baz` is also a property of a Global object.
      However, it is created via property assignment and so has no DontDelete attribute.
      This is why it can be deleted. */
  GLOBAL_OBJECT.baz = 'blah';
  delete GLOBAL_OBJECT.baz; // true
  typeof GLOBAL_OBJECT.baz; // "undefined"

内置对象和DontDelete

这就是全部:属性中一个独特的特性控制着这个属性是否能被删除。注意,内置对象的一些属性也有特定的DontDelete 特性,因此,它不能被删除。特定的Arguments 变量(或者,正如我们现在了解的,激活对象的属性),任何函数实例的length属性也拥有DontDelete 特性。

  (function(){
    /* can't delete `arguments`, since it has DontDelete */
    delete arguments; // false
    typeof arguments; // "object"
    /* can't delete function's `length`; it also has DontDelete */
    function f(){}
    delete f.length; // false
    typeof f.length; // "number"
  })();

与函数参数相对应的创建的属性也有DontDelete 特性,因此也不能被删除。

(function(foo, bar){
    delete foo; // false
    foo; // 1
    delete bar; // false
    bar; // 'blah'
  })(1, 'blah');

未声明的赋值

可能还记得未声明的赋值在一个全局对象上创建一个属性。除非它在全局对象之前的作用域中的某个地方可见。现在我们知道属性分配与变量声明之间的差异,后者设置了DontDelete 特性,而前者没有--应该很清楚未声明的赋值创建了一个可删除的属性

  var GLOBAL_OBJECT = this;
  /* create global property via variable declaration; property has DontDelete*/
  var foo = 1;
  /* create global property via undeclared assignment; property has no DontDelete */
  bar = 2;
  delete foo; // false
  typeof foo; // "number"
  delete bar; // true
  typeof bar; // "undefined"

请注意,该特性是在属性创建的过程中确定的(例如:none)。后来的赋值不会修改现有属性已经存在的特性,理解这一点很重要。

  /* `foo` is created as a property with DontDelete */
  function foo(){}
  /* Later assignments do not modify attributes. DontDelete is still there! */
  foo = 1;
  delete foo; // false
  typeof foo; // "number"
  /* But assigning to a property that doesn't exist,
     creates that property with empty attributes (and so without DontDelete) */
  this.bar = 1;
  delete bar; // true
  typeof bar; // "undefined"

Firebug 困惑

那么,在Firebug中会发生什么呢?为什么在控制台中定义的变量可以被删除,难道与我们刚才了解到相反?很好,我先前说过,当涉及到的变量声明,Eval 代码(Eval code)有一个特殊的行为。在Eval 代码(Eval code)中声明的变量实际上没有创建DontDelete 特性。

  eval('var foo = 1;');
  foo; // 1
  delete foo; // true
  typeof foo; // "undefined"confusion

同样,在函数代码(Function code)调用也是如此:

  (function(){
    eval('var foo = 1;');
    foo; // 1
    delete foo; // true
    typeof foo; // "undefined"
  })();

这是Firebug的异常行为的要点,在控制台的所有文本似乎是作为Eval 代码(Eval code)来解析和执行的,而不是作为一个全局对象或函数对象,显然,任何声明的变量没有DontDelete特性,因此可以很容易地删除,应该意识到正常全局代码和Firebug控制台之间的分歧。

通过eval删除变量

这个有趣的eval属性,连同ECMAScript 其它方面的技巧可以让我们删除不可删除的属性。在同一个执行上下文中,函数声明能覆盖同一名字的变量。

  function x(){ }
  var x;
  typeof x; // "function"

注意函数如何获得优先权并覆盖同名变量(或者换句话说,变量对象相同的属性)。这是因为函数声明在变量声明之后实例化,并且可以覆盖它们。函数声明不仅取代了先前的属性值,而且也取代了属性特性。如果我们通过eval声明函数,该函数也应该替换自身的属性特性。既然在eval内声明的变量没有DontDelete特性,那么实例化这个新函数应该从本质上消除属性中现有的DontDelete特性,是的这个属性可以删除(当然也就改变引用新创建函数的值)。

 var x = 1;
  /* Can't delete, `x` has DontDelete */
  delete x; // false
  typeof x; // "number"
  eval('function x(){}');
  /* `x` property now references function, and should have no DontDelete */
  typeof x; // "function"
  delete x; // should be `true`
  typeof x; // should be "undefined"

遗憾的是,这类欺骗在我尝试中并不总是运行,我可能丢失了一些东西,或者这种行为过于简单不足以引起注意。

浏览器兼容性

从理论上认识事物的工作原理是有用的,但实际影响是至关重要的。当涉及到variable/property creation/deletion时,浏览器遵循标准吗?在大多数是的。
我写了一个简单的测试包检测Global code、Function code 和Eval code代码delete 运算符的兼容性。测试包同时检查 -- delete运算符的返回值,以及应被删除的属性是否被删除的。delete 运算符返回truefalse并不重要,重要的是有DontDelete特性不被删除,反之亦然。
现代浏览器一般都相当兼容,除了这个我早期提到的这个eval特性。下面的浏览器完全通过测试包:Opera 7.54+、Firefox 1.0+、Safari 3.1.2+、Chrome 4+。
Safari 2.x 和3.0.4在删除函数参数时有些问题,这些属性似乎没有创建DontDelete,所以可以删除它们。Safari 2.x 甚至有更多问题,删除非引用(例如delete 1)抛出错误;函数声明创建了可删除属性(但奇怪是变量声明不是),在eval中的变量声明成为不可删除的(但函数声明不是)。
与Safari相似,Konqueror (3.5,但不是 4.3)当删除非引用(例如delete 1)抛出错误,它错误使函数参数可以删除。

Gecko DontDelete bug

Gecko 1.8.x浏览器--Firefox 2.x、 Camino 1.x、Seamonkey 1.x等显示一个有趣的bug:对一个属性明确地赋值可以删除它的DontDelete特性,即使该属性是通过变量或函数声明来创建的。

function foo(){}
    delete foo; // false (as expected)
    typeof foo; // "function" (as expected)
    /* now assign to a property explicitly */
    this.foo = 1; // erroneously clears DontDelete attribute
    delete foo; // true
    typeof foo; // "undefined"
    /* note that this doesn't happen when assigning property implicitly */
    function bar(){}
    bar = 1;
    delete bar; // false
  typeof bar; // "number" (although assignment replaced property)

出乎意料的是,IE5.5 – 8全部通过测试包,删除非引用(例如delete 1)抛出错误(就像在老版的Safari一样)。但事实上有更严重bug存在IE中,这不会立即显现。这些bug都与全局对象相关。

IE bugs

整个章节仅仅为了IE中的bug,想不到吧!
在IE浏览器中(至少是IE6-IE8),下面的表达式抛出错误(在全局代码中执行):

this.x = 1;
delete x; // TypeError: Object doesn't support this action

这个也是一样,但异常不同,只是更有趣:

var x = 1;
delete this.x; // TypeError: Cannot delete 'this.x'

IE中看起来好像在全局代码中声明变量不能在全局对象中创建属性。通过赋值创建属性(this.x = 1),然后通过delete删除x将抛出错误。通过声明创建创建属性(var x = 1),然后通过delete this.x删除将抛出另外一个错误。
但这还没完。实际上通过明确的赋值创建的属性在删除时始终引发错误。这不仅是一个错误,而且创建的属性似乎设置了DontDelete特性,这当然不应该有:

this.x = 1;
delete this.x; // TypeError: Object doesn't support this action
typeof x; // "number" (still exists, wasn't deleted as it should have been!)
delete x; // TypeError: Object doesn't support this action
typeof x; // "number" (wasn't deleted again)

与我们思考的相反,未声明的变量(应该在一个全局对象中创建属性)在IE中创建了可删除属性

x = 1;
delete x; // true
typeof x; // "undefined"

但是,如果您尝试通过“this”引用在全局代码中删除它(delete this.x ),一个熟悉的错误弹出:

x = 1;
delete this.x; // TypeError: Cannot delete 'this.x'

如果我们总结这些行为,从全局代码中delete this.x 似乎是不成功的。当涉及到的属性是通过显式声明(this.x = 1 )来创建的,delete 将抛出一个错误。当属性是通过未声明的赋值(x = 1 )或声明(var x = 1 )来创建属性时,delete 将抛出另一个错误。
另一方面,当涉及到的属性是通过显式声明(this.x = 1 )创建时,delete x 抛出错误。如果一个属性是通过声明(var x = 1 )来创建的,删除根本不会发生,并返回正确的false。如果属性是通过未声明的方式(x = 1)创建,删除操作将按预期进行。
去年九月我正在思考这个问题,Garrett Smith 建议“在IE中全局变量对象作为一个JScript对象,全局对象有宿主执行”。Garrett 引用Eric Lippert’s blog entry ,我们可以通过一些测试验证这些理论。请注意,thiswindow似乎引用同一对象(如果我们相信“===”运算符),但变量对象(在一个声明的函数中的对象)不同于这一点。

/* in Global code */
function getBase(){ return this; }
getBase() === this.getBase(); // false
this.getBase() === this.getBase(); // true
window.getBase() === this.getBase(); // true
window.getBase() === getBase(); // false

误区

理解事物为什么那么工作是一种难以言说的美,我在网上已经看到了与delete运算符误解相关的误区。例如,在关于栈溢出的回答(评分出其不意的效果高)中,它自信的解释道:“delete is supposed to be no-op when target isn’t an object property ”。现在,我们已经理解了delete 行为的核心,很清楚这个答案是不准确的。delete 不区分变量和属性(事实上,对于删除,这些都是引用),真正的只关心的是DontDelete特性(和属性存在)。
非常有意思的看到这个误解如何相互影响,在同样一个线程中,有人首先提出要直接删除变量(除非它是在eval中声明,否则不会生效),接着另外一个人提出一种错误的纠正方法--在全局中可能删除变量,但在函数内不行。
在网站上解释Javascript 最好小心,最好总是抓住问题的核心。

‘delete’和宿主对象

delete 的算法大概是这样:

  1. 如果操作不是一个引用,返回true
  2. 如果一个对象没有直接的属性,返回true;(我们知道,对象可以是激活对象,可以是全局象);
  3. 如果一个属性存在并有DontDelete特性,返回false
  4. 否则,删除属性并返回true

但是,宿主对象的delete 运算符的行为难以预测。实际上并没有错:除了少数几个,宿主对象是允许执行任何类型的运算行为的(按规范),如read(内部的[get]方法)、write(内部的[put]方法)或delete(内部的[delete]方法)。这个定制的[[Delete]]行为使得宿主对象如此混乱。
在IE中我们已经看到一些古怪的行为,如果删除某些对象(明显作为宿主对象来执行)将抛出错误。Firefox的一些版本在尝试删除window.location时将抛出错误。当涉及到宿主对象时,你不能信任delete返回的任何值。看看在Firefox会有什么发生:

/* "alert" is a direct property of `window` (if we were to believe `hasOwnProperty`) */
window.hasOwnProperty('alert'); // true
delete window.alert; // true
typeof window.alert; // "function"

删除window.alert 返回true,虽然这个属性什么也没有,它应该导致这个结果。它保留了一个引用(因此在第一步中不应该返回true),它是窗口对象的直接属性(因此第二步中不能返回true)。唯一的办法让delete返回true是在第四步之后真正删除属性。但是,属性是永远不会被删除的。
这个故事的寓意在于永远不要相信宿主对象

ES5严格模式

那么,ECMAScript 5th edition 的严格模式可以拿到台面上来了。一些限制正被引入,当delete运算符是一个变量、函数参数或函数标识符的直接引用时将抛出SyntaxError。另外,如果属性内部有[[Configurable]] == false,将抛出TypeError。

(function(foo){
   "use strict"; // enable strict mode within this function
    var bar;
    function baz(){}
    delete foo; // SyntaxError (when deleting argument)
    delete bar; // SyntaxError (when deleting variable)
    delete baz; // SyntaxError (when deleting variable created with function declaration)
    /* `length` of function instances has { [[Configurable]] : false } */
    delete (function(){}).length; // TypeError
})();

另外,删除未声明的变量(换句话说,没有找到的引用)也抛出SyntaxError。

    "use strict";
  delete i_dont_exist; // SyntaxError

正如你所理解的那样,考虑到删除变量、函数声明和参数会导致如此多得混淆,所有这些限制就有点意义。与不声不响的忽略删除行为相反,严格模式应该采取更积极的、更具有描述性的措施。

总结

这篇文章是冗长的,我打算去讨论用delete删除数组选项和它的含义。你可以随时参考MDC 的文章了解具体的解释(或阅读规范,自己实验)。
这是Javascript中delete运算符工作的简短概要:

  • 变量和函数声明要么是激活对象的属性,要么是全局对象的属性;
  • 属性有一些特性,其中之一就是DontDelete,它决定一个属性是否能删除;
  • Global 和Function code 中的变量和函数声明总是有DontDelete特性;
  • 函数参数也是激活对象的属性,具有DontDelete特性;
  • 在Eval代码中的变量和函数声明总是创建没有DontDelete特性的属性;
  • 新的属性总是带有空的特性(因此没有DontDelete特性);
  • 宿主对象允许对删除作出反应,无论它们是否愿意如此;

如果你想了解更多这里这里描述的东西,请参阅ECMA-262 3rd edition specification
我希望你喜欢这篇综述,并能学到新东西。任何疑问、建议、更正,一律欢迎。
相关阅读:

原文地址:Understanding delete
转载地址:http://www.denisdeng.com/?p=858

Pro Android 2. 笔记 – 2 名词定义

View
Views are user interface (UI) elements that form the basic building blocks of a user
interface. Views are hierarchical and they know how to draw themselves. A view could
be a button or a label or a text field, or lots of other UI elements. If you are familiar with
views in J2EE and Swing then you’ll understand views in Android.
Activity
An activity is a user interface concept. An activity usually represents a single screen in
your application. It generally contains one or more views, but it doesn’t have to.
Moreover, other concepts in Android could better represent a viewless activity (as you抣l
see in the service section shortly).
Intent
An intent generically defines an 搃ntention?to do some work. Intents encapsulate several
concepts, so the best approach to understanding them is to see examples of their use.
You can use intents to perform the following tasks:
.. Broadcast a message
.. Start a service
.. Launch an activity
.. Display a web page or a list of contacts
.. Dial a phone number or answer a phone call
Intents are not always initiated by your application they’re also used by the system to
notify your application of specific events (such as the arrival of a text message).
Intents can be explicit or implicit. If you simply say that you want to display a URL, the
system will decide what component will fulfill the intention. You can also provide specific
information about what should handle the intention. Intents loosely couple the action
and action handler.
Content Provider
Data sharing among mobile applications on a device is common. Therefore, Android
defines a standard mechanism for applications to share data (such as a list of contacts)
without exposing the underlying storage, structure, and implementation. Through
content providers, you can expose your data and have your applications use data from
other applications.
Service
Services in Android resemble services you see in Windows or other platforms梩hey抮e
background processes that can potentially run for a long time. Android defines two
types of services: local services and remote services. Local services are components
that are only accessible by the application that is hosting the service. Conversely,
remote services are services that are meant to be accessed remotely by other
applications running on the device.
An example of a service is a component that is used by an e-mail application to poll for
new messages. This kind of service might be a local service if the service is not used by
other applications running on the device. If several applications use the service, then it
would be implemented as a remote service. The difference, as you抣l see in Chapter 8, is
in startService() vs. bindService().
You can use existing services and also write your own services by extending the
Service class.
AndroidManifest.xml
AndroidManifest.xml, which is similar to the web.xml file in the J2EE world, defines the
contents and behavior of your application. For example, it lists your application
activities and services, along with the permissions the application needs to run.
Android Virtual Devices
An Android Virtual Device (AVD) allows developers to test their applications without
hooking up an actual Android phone. AVDs can be created in various configurations to
emulate different types of real phones.

Pro Android 2. 笔记

Dalvik 与 class files
These issues led Google to revisit the standard JVM implementation in many respects.
(The key figure in Google’s implementation of this JVM is Dan Bornstein, who wrote the
Dalvik VM—Dalvik is the name of a town in Iceland.) First, the Dalvik VM takes the
generated Java class files and combines them into one or more Dalvik Executable (.dex)
files. It reuses duplicate information from multiple class files, effectively reducing the
space requirement (uncompressed) by half from a traditional .jar file. For example, the
.dex file of the web browser app in Android is about 200K, whereas the equivalent
uncompressed .jar version is about 500K. The .dex file of the alarm clock app is about
50K, and roughly twice that size in its . jar version.
===========
Second, Google has fine-tuned the garbage collection in the Dalvik VM, but it has
chosen to omit a just-in-time (JIT) compiler, in early releases. The 2.0 codebase seem to
have the necessary sources for a JIT compiler but is not enabled in the final release
2.2 引入了JIT — 通过某种算法去收集和抽取那些最常用代码(或者是最符合算法需求的),把他们转化成native指令来提供执行效率。
 
==========
Finally, the Dalvik VM uses a different kind of assembly-code generation, in which it uses
registers as the primary units of data storage instead of the stack.
register一般指是CPU的一些存储器,不包括cache。stack是用于程序的函数保存临时变量的内存,如函数调用时保存某些寄存器的值和函数的临时变量(入栈),当函数结束时,将释放掉临时变量,恢复函数调用前的寄存器的值(出栈)。
========================================
This performance paranoia extends into the rest of the Android SDK. For example, the
Android SDK uses XML extensively to define UI layouts. However, all of this XML is
compiled to binary files before these binary files become resident on the devices
.class files   -> .dex    .xml   -> binary files
 
========================================
Most of the application framework accesses these core libraries through the Dalvik VM,
the gateway to the Android Platform. As we indicated in the previous sections, Dalvik is
optimized to run multiple instances of VMs. As Java applications access these core
libraries, each application gets its own VM instance.

Android 与 XML

Android 里很多配置文件是存在 xml 里的,但是xml 描述信息的效率是非常低的。如果直接布署到移动设备上非常占资源。
其实把App在安装到移动设置上时。AAPT(Android Assert Packaging Tool) 会将 xml 转化成 二进制文件的形式存储。在移动设备上读取这些配置项的时候,也是从二进制文件里读取。此处应当是向上封装的。

Android 下定时触发 service

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        final AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE) ;
        long elapseTime = 60*1000l;
        Intent toWake = new Intent(this, PiggyService.class);
        final PendingIntent wakeupIntent = PendingIntent.getService(this, 0, toWake,0  );
        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+elapseTime, wakeupIntent);
        return START_NOT_STICKY;
    }

START_NOT_STICKY表示要求的系统优先级要低,允许系统回归该组件,只是定时触发唤醒而已。
同理还有START_STICKY 表示要求系统不回收该组件(如听歌组件等,回收会影响用户体验的服务)
START_REDELIVER_INTENT表示如果该组件在执行中被系统回收,在重新调用时会复原传入的Intent对象确保中间数据不会丢失。