﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-Calvin's Tech Space</title><link>http://www.blogjava.net/lihao336/</link><description>成于坚忍，毁于浮躁</description><language>zh-cn</language><lastBuildDate>Tue, 28 Apr 2026 14:33:56 GMT</lastBuildDate><pubDate>Tue, 28 Apr 2026 14:33:56 GMT</pubDate><ttl>60</ttl><item><title>[转]不同格式证书导入keystore方法 </title><link>http://www.blogjava.net/lihao336/archive/2012/02/03/369303.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Fri, 03 Feb 2012 02:06:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2012/02/03/369303.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/369303.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2012/02/03/369303.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/369303.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/369303.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java																																				自带的																																																		keytool																																														工具								...&nbsp;&nbsp;<a href='http://www.blogjava.net/lihao336/archive/2012/02/03/369303.html'>阅读全文</a><img src ="http://www.blogjava.net/lihao336/aggbug/369303.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2012-02-03 10:06 <a href="http://www.blogjava.net/lihao336/archive/2012/02/03/369303.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android exchange 账户设置</title><link>http://www.blogjava.net/lihao336/archive/2012/01/30/369036.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Mon, 30 Jan 2012 09:13:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2012/01/30/369036.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/369036.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2012/01/30/369036.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/369036.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/369036.html</trackback:ping><description><![CDATA[输入邮箱，邮箱要Gmail邮箱，就是后缀@gmail.com  输入密码后下一步,<br />关键点： “服务器”一栏，默认为gmail.com，应该改为“<font color="#FF0000">m.google.com</font>”，然后继续即可。<img src ="http://www.blogjava.net/lihao336/aggbug/369036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2012-01-30 17:13 <a href="http://www.blogjava.net/lihao336/archive/2012/01/30/369036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>setComponentEnabledSetting doesn't work on widget</title><link>http://www.blogjava.net/lihao336/archive/2011/12/27/367332.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Tue, 27 Dec 2011 06:14:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2011/12/27/367332.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/367332.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2011/12/27/367332.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/367332.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/367332.html</trackback:ping><description><![CDATA[PackageManager.setComponentEnabledSetting 可以用来禁用某个组件，包括activity，receiver等等。被禁用的组件会被持久化到/data/system/packages.xml中，如：<br /><br />&lt;package name="com.android.setupwizard" codePath="/system/app/SetupWizard.apk" nativeLibraryPath="/data/data/com.android.setupwizard/lib" flags="1" ft="13349457a90" it="13349457a90" ut="13349457a90" version="130" userId="10016"&gt;<br />&lt;sigs count="1"&gt;<br />&lt;cert index="0" /&gt;<br />&lt;/sigs&gt;<br />&lt;disabled-components&gt;<br />&lt;item name="com.android.setupwizard.SetupWizardActivity" /&gt;<br />&lt;/disabled-components&gt;<br />&lt;/package&gt;<br /><br />现在需要在运行时禁用某个widget，同时有一个system property用来标识是否需要禁用。<br />因为widget实际上就是个reveiver，它接收android.appwidget.action.APPWIDGET_UPDATE的action，所以开始的思路是：<br />创建一个BroadcastReceiver，接收Intent.ACTION_BOOT_COMPLETED这个动作，从而在启动完成后调用SystemProperties.get("disable_widget")，如果需要禁用这个widget，那么调用：<br />PackageManager.setComponentEnabledSetting(widgetComponentName，PackageManager.COMPONENT_ENABLED_STATE_ENABLED,<br />                PackageManager.DONT_KILL_APP);<br /><br />但是问题是，调用这个方法disable掉这个widget后，发现必须把设备重启之后才能生效...<br />经过google，发现问题出在com.android.server.AppWidgetService.java。<br />原来开机后，SystemServer会调用AppWidgetService的systemReady()方法，这个方法通过PackageManager查询所有的widget receiver组件，保存到mInstalledProviders变量列表中，并持久化widget信息到/data/system/appwidgets.xml中。<br />而在Launcher上长按添加widget时的那个widget列表信息也是通过AppWidgetService取得mInstalledProviders列表。<br />问题在于我们通过PackageManager.setComponentEnabledSetting（）禁用掉某个widget后，packagemanager确实将这个组件disable了，但是AppWidgetService却没有去从packagemanager reload widget信息，这就导致了mInstalledProviders中保存的widget信息还是开机时load进来的那些信息，并没有与pm进行同步。直到下一次开机调用systemReady重新加载widget信息才会刷新这个列表。<br /><br />参考：<br />Dynamically enabling or disabling a widget with PackageManager.setComponentEnabledSetting does not work<br />http://code.google.com/p/android/issues/detail?id=6533<br /><br />http://blog.csdn.net/yinlijun2004/article/details/6136108<br /><br /><img src ="http://www.blogjava.net/lihao336/aggbug/367332.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2011-12-27 14:14 <a href="http://www.blogjava.net/lihao336/archive/2011/12/27/367332.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]unix/linux中的dup()系统调用</title><link>http://www.blogjava.net/lihao336/archive/2011/12/13/366231.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Tue, 13 Dec 2011 06:20:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2011/12/13/366231.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/366231.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2011/12/13/366231.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/366231.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/366231.html</trackback:ping><description><![CDATA[   在linux纷繁复杂的内核代码中，sys_dup()的代码也许称得上是最简单的之一了，但是就是这么一个简单的系统调用，却成就了unix/linux系统最著名的一个特性：输入/输出重定向。<br />    sys_dup()的主要工作就是用来“复制”一个打开的文件号，使两个文件号都指向同一个文件。既然说简单，我们就首先来看一下它的代码（定义在fs/fcntl.c中）：<br /><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080; "> 1</span> <span style="color: #000000; ">asmlinkage </span><span style="color: #0000FF; ">long</span><span style="color: #000000; "> sys_dup(unsigned </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> fildes)<br /></span><span style="color: #008080; "> 2</span> <span style="color: #000000; ">{<br /></span><span style="color: #008080; "> 3</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> ret </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">-</span><span style="color: #000000; ">EBADF;<br /></span><span style="color: #008080; "> 4</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">struct</span><span style="color: #000000; "> file </span><span style="color: #000000; ">*</span><span style="color: #000000; "> file </span><span style="color: #000000; ">=</span><span style="color: #000000; "> fget(fildes);<br /></span><span style="color: #008080; "> 5</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 6</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> (file)<br /></span><span style="color: #008080; "> 7</span> <span style="color: #000000; ">        ret </span><span style="color: #000000; ">=</span><span style="color: #000000; "> dupfd(file, </span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; "> 8</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> ret;<br /></span><span style="color: #008080; "> 9</span> <span style="color: #000000; ">}<br /></span><span style="color: #008080; ">10</span> <span style="color: #000000; "></span></div><br />而sys_dup()的主体是dupfd()（定义在同一个文件中）：<br /><br /><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080; "> 1</span> <span style="color: #0000FF; ">static</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> dupfd(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; "> file </span><span style="color: #000000; ">*</span><span style="color: #000000; ">file, </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> start)<br /></span><span style="color: #008080; "> 2</span> <span style="color: #000000; ">{<br /></span><span style="color: #008080; "> 3</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">struct</span><span style="color: #000000; "> files_struct </span><span style="color: #000000; ">*</span><span style="color: #000000; "> files </span><span style="color: #000000; ">=</span><span style="color: #000000; "> current</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">files;<br /></span><span style="color: #008080; "> 4</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> ret;<br /></span><span style="color: #008080; "> 5</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 6</span> <span style="color: #000000; ">    ret </span><span style="color: #000000; ">=</span><span style="color: #000000; "> locate_fd(files, file, start);<br /></span><span style="color: #008080; "> 7</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> (ret </span><span style="color: #000000; ">&lt;</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; "> 8</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">goto</span><span style="color: #000000; "> out_putf;<br /></span><span style="color: #008080; "> 9</span> <span style="color: #000000; ">    allocate_fd(files, file, ret);<br /></span><span style="color: #008080; ">10</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> ret;<br /></span><span style="color: #008080; ">11</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">12</span> <span style="color: #000000; ">out_putf:<br /></span><span style="color: #008080; ">13</span> <span style="color: #000000; ">    write_unlock(</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">files</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">file_lock);<br /></span><span style="color: #008080; ">14</span> <span style="color: #000000; ">    fput(file);<br /></span><span style="color: #008080; ">15</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> ret;<br /></span><span style="color: #008080; ">16</span> <span style="color: #000000; ">}<br /></span><span style="color: #008080; ">17</span> <span style="color: #000000; "></span></div><br /><font color="#0000FF">注：dup和dup2的原型如下：<br />#include &lt;unistd.h&gt;<br /><br />int dup(int file_descriptor);<br />int dup2(int file_descriptor1, int file_descriptor2)<br />dup返回的文件描述符总是取最小的可用值<br />dup2返回的文件描述符或者与file_descriptor2相同，或者是第一个大于该参数的可用值。</font><br /><br />    而这么一个简单的系统调用是如何完成重定向这个艰巨的任务的呢？我们不妨先看个例子。<br />   
 当我们在shell下输入如下命令：“echo 
hello!”，这条命令要求shell进程执行一个可执行文件echo，参数为“hello!”。当shell接收到命令之后，先找到
bin/echo，然后fork()出一个子进程让他执行bin/echo，并将参数传递给它，<font color="#FF0000">而这个进程从shell继承了三个标准文件，即标准输入
（stdin），标准输出（stdout）和标准出错信息（stderr），他们三个的文件号分别为0、1、2。</font>而至于echo进程的工作很简单，就是将参数“hello!”写到标准输出文件中去，通常都是我们的显示器上。但是如果我们将命令改成“echo hello! &gt; 
foo”，则在执行时输出将会被重定向到磁盘文件foo中<font color="#0000FF">（注：重定向于文件描述符有关）</font>。我们假定在此之前该shell进程只有三个标准文件打开，文件号分别为0、1、2，以上命令行将按如下序列执行：<br />    (1) 打开或创建磁盘文件foo，如果foo中原来有内容，则清除原来内容，其文件号为3。<br />    (2) 通过dup()复制文件stdout，即将文件号1出的file结构指针复制到文件号4处，目的是将stdout的file指针暂时保存一下<br />    (3) 关闭stdout，即1号文件，但是由于4号文件对stdout也同时有个引用，所以stdout文件并未真正关闭，只是腾出1号文件号位置。<br />    (4) 通过dup()，复制3号文件（即磁盘文件foo），由于1号文件关闭，其位置空缺，故3号文件被复制到1号，即进程中原来指向stdout的指针指向了foo。<br />   
 (5) 
通过系统调用fork()和exec()创建子进程并执行echo，子进程在执行echo前夕关闭3号和4号文件，只留下0、1、2三个文件，请注意，这
时的1号文件已经不是stdout而是磁盘文件foo了。当echo想向stdout文件写入“hello!”时自然就写入到了foo中。<br />    (6) 回到shell后，关闭指向foo的1号与3号文件文件，再用dup()和close()将2号恢复至stdout，这样shell就恢复了0、1、2三个标准输入/输出文件。<br /><br />   
 
由此可见，<font color="#FF0000">当echo程序（或其他）在运行的时候并不知道stdout（对于stdin和stderr同样）指向什么，进程与实际输出文件或设备的结合是在运行时由其父进程“包办”的。这样就简化了子进程的程序设计，因为在设计时只要跟三个逻辑上存在的文件打交道就可以了</font>。可能有人会觉得这很像面向对象中
的多态和重载，没有什么新奇之处，但是如果你活在30甚至40年前，可能你会改变你的看法。 
<img src ="http://www.blogjava.net/lihao336/aggbug/366231.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2011-12-13 14:20 <a href="http://www.blogjava.net/lihao336/archive/2011/12/13/366231.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Activity的onSaveInstanceState调用时机</title><link>http://www.blogjava.net/lihao336/archive/2011/11/22/364585.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Tue, 22 Nov 2011 09:56:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2011/11/22/364585.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/364585.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2011/11/22/364585.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/364585.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/364585.html</trackback:ping><description><![CDATA[http://ice-k.iteye.com/blog/1018956<br /><br />Activity的生命周期里并没有提到onSaveInstanceState的触发，这个函数提供了为我们在某些情况下保存Activity信息的机会，但需要注意的是这个函数不是什么时候都会被调用的，官方文档解释的比较清楚，特此
<br />翻译一下。
<br />原文出处：android-sdk-windows-1.5_r3/docs/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
<br />protected void onSaveInstanceState (Bundle outState)
<br />       Called to retrieve per-instance state from an activity before
 being killed so that the state can be restored in onCreate(Bundle) or 
onRestoreInstanceState(Bundle) (the Bundle populated by this method will
 be passed to both). This method is called before an activity may be 
killed so that when it comes back some time in the future it can restore
 its state. For example, if activity B is launched in front of activity 
A, and at some point activity A is killed to reclaim resources, activity
 A will have a chance to save the current state of its user interface 
via this method so that when the user returns to activity A, the state 
of the user interface can be restored via onCreate(Bundle) or 
onRestoreInstanceState(Bundle).
<br /><br />    
在activity被杀掉之前调用保存每个实例的状态,以保证该状态可以在onCreate(Bundle)或者
onRestoreInstanceState(Bundle) 
(传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。这个方法在一个activity被杀死前调用，当该
activity在将来某个时刻回来时可以恢复其先前状态。例如，如果activity B启用后位于activity 
A的前端，在某个时刻activity 
A因为系统回收资源的问题要被杀掉，A通过onSaveInstanceState将有机会保存其用户界面状态，使得将来用户返回到activity 
A时能通过onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢复界面的状态。
<br /><br />    Do not confuse this method with activity lifecycle callbacks 
such as onPause(), which is always called when an activity is being 
placed in the background or on its way to destruction, or onStop() which
 is called before destruction. One example of when onPause() and 
onStop() is called and not this method is when a user navigates back 
from activity B to activity A: there is no need to call 
onSaveInstanceState(Bundle) on B because that particular instance will 
never be restored, so the system avoids calling it. An example when 
onPause() is called and not onSaveInstanceState(Bundle) is when activity
 B is launched in front of activity A: the system may avoid calling 
onSaveInstanceState(Bundle) on activity A if it isn't killed during the 
lifetime of B since the state of the user interface of A will stay 
intact. 
<br />   
<br />    
不要将这个方法和activity生命周期回调如onPause()或onStop()搞混淆了，onPause()在activtiy被放置到背景或者
自行销毁时总会被调用，onStop()在activity被销毁时被调用。一个会调用onPause()和onStop()，但不触发
onSaveInstanceState的例子是当用户从activity B返回到activity 
A时：没有必要调用B的onSaveInstanceState(Bundle)，此时的B实例永远不会被恢复，因此系统会避免调用它。一个调用
onPause()但不调用onSaveInstanceState的例子是当activity B启动并处在activity 
A的前端：如果在B的整个生命周期里A的用户界面状态都没有被破坏的话，系统是不会调用activity 
A的onSaveInstanceState(Bundle)的。
<br /><br />    The default implementation takes care of most of the UI 
per-instance state for you by calling onSaveInstanceState() on each view
 in the hierarchy that has an id, and by saving the id of the currently 
focused view (all of which is restored by the default implementation of 
onRestoreInstanceState(Bundle)). If you override this method to save 
additional information not captured by each individual view, you will 
likely want to call through to the default implementation, otherwise be 
prepared to save all of the state of each view yourself. If called, this
 method will occur before onStop(). There are no guarantees about 
whether it will occur before or after onPause().
<br /><br />      
默认的实现负责了大部分UI实例状态(的保存)，采用的方式是调用UI层上每个拥有id的view的onSaveInstanceState() 
，并且保存当前获得焦点的view的id(所有保存的状态信息都会在默认的onRestoreInstanceState(Bundle)实现中恢复)。
如果你覆写这个方法来保存额外的没有被各个view保存的信息，你可能想要在默认实现过程中调用或者自己保存每个视图的所有状态。如果被调用，这个方法会
在onStop()前被触发，但系统并不保证是否在onPause()之前或者之后触发。
<br /><br />很多不明白Activity类中包含的onSaveInstanceState和onRestoreInstanceState有什么用，首先声
明下使用这两个方法时一定要注意情况和了解Activity的生命周期，否则有的时候  
onSaveInstanceState和onRestoreInstanceState 
可能不会被触发，虽然他们都是Activity的重写方法。（文/Android开发网）
<br /><br />他们比较常用到的地方是 
Sensor、Land和Port布局的自动切换，过去Android开发网曾经说过解决横屏和竖屏切换带来的数据被置空或者说onCreate被重复调
用问题，其实Android提供的onSaveInstanceState方法可以保存当前的窗口状态在即将布局切换前或当前Activity被推入历史
栈，其实布局切换也调用过onPause所以被推入Activity的history 
stack，如果我们的Activity在后台没有因为运行内存吃紧被清理，则切换回时会触发onRestoreInstanceState方法。
<br /><br />这两个方法中参数均为Bundle，可以存放类似 SharedPreferences 的数据，所以使用它们作为当前窗口的状态保存是比较合适的。实际使用代码
<br />@Override
<br />  protected void onSaveInstanceState(Bundle outState){
<br />            outState.putString("lastPath", "/sdcard/android123/cwj/test");
<br />  }
<br /><br /><br />@Override
<br />public void onRestoreInstanceState(Bundle savedInstanceState) {
<br />super.onRestoreInstanceState(savedInstanceState);
<br /><br />String cwjString = savedInstanceState.getString("lastPath");
<br />}
<br /><br />onSaveInstanceState和onRestoreInstanceState触发的时机
<br />已有 199 次阅读 2011-3-10 10:32 |个人分类:Android|关键词:onSaveInstanceState onRestoreInstanceState
<br />先看Application Fundamentals上的一段话：
<br /> Android calls onSaveInstanceState() before the activity becomes 
vulnerable to being destroyed by the system, but does not bother calling
 it when the instance is actually being destroyed by a user action (such
 as pressing the BACK key)
<br />从这句话可以知道，当某个activity变得“容易”被系统销毁时，该activity的onSaveInstanceState就会被执行，除非该activity是被用户主动销毁的，例如当用户按BACK键的时候。
<br />注意上面的双引号，何为“容易”？言下之意就是该activity还没有被销毁，而仅仅是一种可能性。这种可能性有哪些？通过重写一个 
activity的所有生命周期的onXXX方法，包括onSaveInstanceState和onRestoreInstanceState方法，我
 们可以清楚地知道当某个activity（假定为activity 
A）显示在当前task的最上层时，其onSaveInstanceState方法会在什么时候被执行，有这么几种情况：
<br />1、当用户按下HOME键时。这是显而易见的，系统不知道你按下HOME后要运行多少其他的程序，自然也不知道activity A是否会被销毁，故系统会调用onSaveInstanceState，让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
<br />2、长按HOME键，选择运行其他的程序时。
<br />3、按下电源按键（关闭屏幕显示）时。
<br />4、从activity A中启动一个新的activity时。
<br />5、屏幕方向切换时，例如从竖屏切换到横屏时。在屏幕切换之前，系统会销毁activity A，在屏幕切换之后系统又会自动地创建activity A，所以onSaveInstanceState一定会被执行
<br />总而言之，onSaveInstanceState的调用遵循一个重要原则，即当系统“未经你许可”时销毁了你的activity，则 
onSaveInstanceState会被系统调用，这是系统的责任，因为它必须要提供一个机会让你保存你的数据（当然你不保存那就随便你了）。
<br />至于onRestoreInstanceState方法，需要注意的是，onSaveInstanceState方法和 
onRestoreInstanceState方法“不一定”是成对的被调用的，onRestoreInstanceState被调用的前提 
是，activity A“确实”被系统销毁了，而如果仅仅是停留在有这种可能性的情况下，则该方法不会被调用，例如，当正在显示activity 
A的时候，用户按下HOME键回到主界面，然后用户紧接着又返回到activity A，这种情况下activity 
A一般不会因为内存的原因被系统销毁，故activity A的onRestoreInstanceState方法不会被执行
<br />另外，onRestoreInstanceState的bundle参数也会传递到onCreate方法中，你也可以选择在onCreate方法中做数据还原
  <img src ="http://www.blogjava.net/lihao336/aggbug/364585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2011-11-22 17:56 <a href="http://www.blogjava.net/lihao336/archive/2011/11/22/364585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>InputStream.available()方法</title><link>http://www.blogjava.net/lihao336/archive/2011/11/18/364225.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Fri, 18 Nov 2011 06:16:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2011/11/18/364225.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/364225.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2011/11/18/364225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/364225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/364225.html</trackback:ping><description><![CDATA[首先这个方法不能用来判断文件长度！获取文件长度可以使用File.length()方法，它返回一个long类型的以字节为单位的值。<br /><br />看文档：<br />Returns an estimated number of bytes that can be read or skipped without blocking for more input.<br /><br /><b>Note that this method provides such a weak guarantee that it is not very useful in practice.</b><br /><br />Firstly, the guarantee is "without blocking for more input" rather than "without blocking": a read may still block waiting for I/O to complete — the guarantee is merely that it won't have to wait indefinitely for data to be written. The result of this method should not be used as a license to do I/O on a thread that shouldn't be blocked.<br /><br />Secondly, the result is a conservative estimate and may be significantly smaller than the actual number of bytes available. In particular, an implementation that always returns 0 would be correct. In general, callers should only use this method if they'd be satisfied with treating the result as a boolean yes or no answer to the question "is there definitely data ready?".<br /><br />Thirdly, the fact that a given number of bytes is "available" does not guarantee that a read or skip will actually read or skip that many bytes: they may read or skip fewer.<br /><br /><b>It is particularly important to realize that you must not use this method to size a container and assume that you can read the entirety of the stream without needing to resize the container. Such callers should probably write everything they read to a ByteArrayOutputStream and convert that to a byte array. Alternatively, if you're reading from a file, length() returns the current length of the file (though assuming the file's length can't change may be incorrect, reading a file is inherently racy).</b><br /><br />The default implementation of this method in InputStream always returns 0. Subclasses should override this method if they are able to indicate the number of bytes available.<br /><br /><img src ="http://www.blogjava.net/lihao336/aggbug/364225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2011-11-18 14:16 <a href="http://www.blogjava.net/lihao336/archive/2011/11/18/364225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>小端存储和大端存储</title><link>http://www.blogjava.net/lihao336/archive/2011/11/15/363850.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Tue, 15 Nov 2011 07:36:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2011/11/15/363850.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/363850.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2011/11/15/363850.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/363850.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/363850.html</trackback:ping><description><![CDATA[所有网络协议都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。当两台采用不同字节序的主机通信时，在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。
<p><wbr> <wbr> <wbr> 判断小端还是大端规则的方法：</wbr></wbr></wbr></p><p><wbr>int x = 1;<br /><wbr>if(*(char *)&amp;x == 1)//取x指针强制转换为char*类型再取值，此时取到的值是int最低字节值<br /><wbr> <wbr> <wbr> <wbr> printf(“little-endian\n”);<br /><wbr>else<br /><wbr> <wbr> <wbr> <wbr> printf(“big-endian\n”);</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></p><p><wbr></wbr></p><p><wbr> <wbr> <wbr> <wbr> 另外补充：</wbr></wbr></wbr></wbr></p><p>1．BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有关的，每一种CPU不是BIG-ENDIAN就是LITTLE-
ENDIAN、。IA架构的CPU中是Little-Endian，而PowerPC 
、SPARC和Motorola处理器。这其实就是所谓的主机字节序。而网络字节序是指数据在网络上传输时是大头还是小头的，在Internet的网络字
节序是BIG-ENDIAN。所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序，JAVA字节序也是BIG-ENDIAN。</p><p>2．所以在用C/C++写通信程序时，在发送数据前务必用htonl和htons去把整型和短整型的数据进行从主机字节序到网络字节序的转换，而接
收数据后对于整型和短整型数据则必须调用ntohl和ntohs实现从网络字节序到主机字节序的转换。如果通信的一方是JAVA程序、一方是C/C++程
序时，则需要在C/C++一侧使用以上几个方法进行字节序的转换，而JAVA一侧，则不需要做任何处理，因为JAVA字节序与网络字节序都是BIG-
ENDIAN，只要C/C++一侧能正确进行转换即可（发送前从主机序到网络序，接收时反变换）。如果通信的双方都是JAVA，则根本不用考虑字节序的问
题了。</p><p><br /></p><p>转自<a href="http://www.embest.net/index.php/archives/259">http://www.embest.net/index.php/archives/259</a><br /></p><img src ="http://www.blogjava.net/lihao336/aggbug/363850.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2011-11-15 15:36 <a href="http://www.blogjava.net/lihao336/archive/2011/11/15/363850.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>重写equals和hashCode方法</title><link>http://www.blogjava.net/lihao336/archive/2011/11/10/363457.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Thu, 10 Nov 2011 10:25:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2011/11/10/363457.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/363457.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2011/11/10/363457.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/363457.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/363457.html</trackback:ping><description><![CDATA[以下总结自effective java.<br />实现equals方法的过程如下：<br />1 使用==运算符来判断是否引用同一个对象。<br />2 使用instance of操作符来判断参数是否是正确的类型。<br />3 将实参cast成正确的类型。<br />4 对于每个关键属性，进行比较:<br />对于非float或double的primitive类型，使用==判断等价性;<br />对于floa类型，先使用Float.floatToIntBits转换成int类型，然后使用==比较int类型的值;<br />对于double类型，先使用Double.doubleToLongBits转换成long类型，然后使用==比较long类型;<br />对于对象引用，递归的调用equals方法。<br />对于数组类型，对其中的元素进行上述的操作,或者使用Arrays.equals方法(version 1.5)。<br />为了避免NPE，可以使用<br />field == null ? o.field == null : fleld.equals(o.field);<br /><br />重写hashCode方法如下：<br />1 把某个非零常数值，例如17，保存在int变量result中；<br />2 对于对象中每一个关键域f（指equals方法中考虑的每一个域）,计算散列码c：<br />2.1 boolean型，计算(f ? 0 : 1);<br />2.2 byte,char,short型，计算(int);<br />2.3 long型，计算(int) (f ^ (f&gt;&gt;&gt;32));<br />2.4 float型，计算Float.floatToIntBits(f);<br />2.5 double型，计算Double.doubleToLongBits(f)得到一个long，再执行[2.3];<br />2.6 对象引用，递归调用它的hashCode方法;<br />2.7 数组域，对其中每个元素按照上面的规则计算hash code。<br />3 将上面计算得到的散列码保存到int变量c，然后执行 result=37*result+c;<br />4 返回result。<br /><br /><img src ="http://www.blogjava.net/lihao336/aggbug/363457.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2011-11-10 18:25 <a href="http://www.blogjava.net/lihao336/archive/2011/11/10/363457.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用javap生成方法签名</title><link>http://www.blogjava.net/lihao336/archive/2011/10/24/361901.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Mon, 24 Oct 2011 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2011/10/24/361901.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/361901.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2011/10/24/361901.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/361901.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/361901.html</trackback:ping><description><![CDATA[使用JNI在native内调用java方法时，需要知道java方法的方法签名，利用javap工具可以方便的生成签名。由于java方法签名在jni层的表示方法的复杂性，利用这个工具生成签名信息可以避免人工分析带来的错误。<br />如：<br /><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080; "> 1</span> <span style="color: #0000FF; ">package</span><span style="color: #000000; "> com.demo;<br /></span><span style="color: #008080; "> 2</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 3</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> SigTest {<br /></span><span style="color: #008080; "> 4</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 5</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">static</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">final</span><span style="color: #000000; "> String name </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; "> 6</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 7</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> getName(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">[] data,</span><span style="color: #0000FF; ">long</span><span style="color: #000000; "> index) {<br /></span><span style="color: #008080; "> 8</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; "> 9</span> <span style="color: #000000; ">    }<br /></span><span style="color: #008080; ">10</span> <span style="color: #000000; ">}<br /></span><span style="color: #008080; ">11</span> <span style="color: #000000; "></span></div><br />[calvin@calvin-desktop /tmp 15:59:50 ] <br />$ javac SigTest.java <br />[calvin@calvin-desktop /tmp 15:59:57 ] <br />$ javap -s -p -classpath . <b>SigTest</b><br />Compiled from "SigTest.java"<br />public class com.demo.SigTest extends java.lang.Object{<br />public static final java.lang.String name;<br />  Signature: Ljava/lang/String;<br />public com.demo.SigTest();<br />  Signature: ()V<br />public int getName(int[], long);<br />  Signature: ([IJ)I<br />static {};<br />  Signature: ()V<br />}<br /><br /><br />-s表示打印签名信息<br />-p表示打印所有函数和成员的签名信息，默认只打印public的签名信息。<br /><br />注意：<br />粗体部分是.class文件的文件名，不要.class后缀，否则提示<br />ERROR:Could not find SigTest.class.<br /><br /><img src ="http://www.blogjava.net/lihao336/aggbug/361901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2011-10-24 16:04 <a href="http://www.blogjava.net/lihao336/archive/2011/10/24/361901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ubuntu10.04安装无线网卡ath9k_htc驱动</title><link>http://www.blogjava.net/lihao336/archive/2011/10/18/361521.html</link><dc:creator>calvin</dc:creator><author>calvin</author><pubDate>Tue, 18 Oct 2011 05:55:00 GMT</pubDate><guid>http://www.blogjava.net/lihao336/archive/2011/10/18/361521.html</guid><wfw:comment>http://www.blogjava.net/lihao336/comments/361521.html</wfw:comment><comments>http://www.blogjava.net/lihao336/archive/2011/10/18/361521.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lihao336/comments/commentRss/361521.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lihao336/services/trackbacks/361521.html</trackback:ping><description><![CDATA[我的USB无线网卡<font color="#000000">型号为TL_WN721N，插在Ubuntu10.04上没有反应。据说10.10以后插上就可以用了，没有测试。<br /><br />第一步 确定</font>ath9k_htc驱动支持<font color="#000000">你的网卡型号<br /></font><a href="http://linuxwireless.org/en/users/Drivers/ath9k_htc/devices" class="postlink">http://linuxwireless.org/en/users/Drivers/ath9k_htc/devices</a> 列出了支持的型号列表，你可以通过lsusb查看自己的网卡型号是否在列表当中。<br /><br /><span class="Apple-style-span">第二步 </span><font color="#000000">安装firmwire<br />从<a href="http://wireless.kernel.org/download/htc_fw/">这里</a>下载</font><span class="Apple-style-span">htc_9271.fw，拷贝到/lib/firmwire下<br /><br /></span><span class="Apple-style-span">第三步 </span><span class="Apple-style-span">安装</span>compact wireless<br />安装compact wireless有打包好的deb包，从<a href="https://sourceforge.net/projects/ath9k-htc/files/ath9k_htc-installer/">这里</a>下载GUI Program to install ath9k_htc，安装完后直接运行，等待安装完成重启机器就可以了。<br />爱折腾的也可以到<a href="http://wireless.kernel.org/download/">http://wireless.kernel.org/download/</a><br />最新的compact wireless驱动，然后编译安装：<br />sudo make
<br />sudo make install
<br />sudo make unload
<br />sudo make load ath9k_htc
<br />重启机器即可。<br /><br />http://forum.ubuntu.com.cn/viewtopic.php?f=116&amp;t=326568&amp;p=2388841<br />http://blog.chinaunix.net/space.php?uid=20620288&amp;do=blog&amp;id=2691282<br /><img src ="http://www.blogjava.net/lihao336/aggbug/361521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lihao336/" target="_blank">calvin</a> 2011-10-18 13:55 <a href="http://www.blogjava.net/lihao336/archive/2011/10/18/361521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>