Android SDK中包含一个“zipalign”的工具,它能够对打包的应用程序进行优化。在你的应用程序上运行zipalign,使得在运行时Android与应用程序间的交互更加有效率。因此,这种方式能够让应用程序和整个系统运行得更快。我们强烈推荐在新的和已经发布的程序上使用zipalign工具来得到优化后的版本——即使你的程序是在老版本的Android平台下开发的。这篇文章将描述zipalign如何有助于性能改善以及如何使用它来优化你的app。

在Android中,每个应用程序中储存的数据文件都会被多个进程访问:安装程序会读取应用程序的manifest文件来处理与之相关的权限问题;Home应用程序会读取资源文件来获取应用程序的名和图标;系统服务会因为很多种原因读取资源(例如,显示应用程序的Notification);此外,就是应用程序自身用到资源文件。

在Android中,当资源文件通过内存映射对齐到4字节边界时,访问资源文件的代码才是有效率的。但是,如果资源本身没有进行对齐处理(未使用zipalign工具),它就必须回到老路上,显式地读取它们——这个过程将会比较缓慢且会花费额外的内存。

对于应用程序开发者来说,这种显式读取方式是相当便利的。它允许使用一些不同的开发方法,包括正常流程中不包含对齐的资源,因此,这种读取方式具有很大的便利性(本段的原始意思请参考原文)。

遗憾的是,对于用户来说,这个情况恰恰是相反的——从未对齐的apk中读取资源比较慢且花费较多内存。最好的情况是,Home程序和未对齐的程序启动得比对齐后的慢(这也是唯一可见的效果)。最坏的情况是,安装一些未对齐资源的应用程序会增加内存压力,并因此造成系统反复地启动和杀死进程。最终,用户放弃使用如此慢又耗电的设备。

幸运的是,对应用程序中的资源作对齐操作很简单:

  • 使用ADT:

o     如果你使用导出向导的话,Eclipse中的ADT插件(从Ver. 0.9.3开始)就能自动对齐Release程序包。使用向导,右击工程属性,选择“Android Tools” > “Export Signed Application Package…”。当然,你还可以通过AndroidManifest.xml编辑器的第一页做到。

  • 使用Ant:

o     Ant编译脚本(从Android 1.6开始)可以对齐程序包。老平台的版本不能通过Ant编译脚本进行对齐,必须手动对齐。

o     从Android 1.6开始,Debug模式下编译时,Ant自动对齐和签名程序包。

o     Release模式下,如果有足够的信息签名程序包的话,Ant才会执行对齐操作,因为对齐处理发生在签名之后。为了能够签名程序包,进而执行对齐操作,Ant必须知道keystore的位置以及build.properties中key的名字。相应的属性名为key.store和key.alias。如果这些属性为空,签名工具会在编译过程中提示输入store/key的密码,然后脚本会执行签名及apk文件的对齐。如果这些属性都没有,Release程序包不会进行签名,自然也就不会进行对齐了。 

  • 手动:

o     为了能够手动对齐程序包,Android 1.6及以后的SDK的tools/文件夹下都有zipalign工具。你可以使用它来对齐任何版本下的程序包。你必须在签名apk文件后进行,使用以下命令:zipalign -v 4 source.apk destination.apk

  • 验证对齐:

o     以下的命令用于检查程序包是否进行了对齐:zipalign -c -v 4 application.apk

我们极力推荐手动zipalign你的应用程序,并确保将最新对齐后的版本提供给用户。此外,别忘了还有你的新应用程序也需要这么做;

from http://www.cnblogs.com/xirihanlin/archive/2010/04/12/1710164.html

posted @ 2012-05-31 11:43 johnny901114 阅读(3) 评论(0) 编辑

public class NetTestActivity extends Activity {

private static final int CMNET = 3;
private static final int CMWAP = 2;
private static final int WIFI = 1;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getAPNType(this);
}

/**
* 获取当前的网络状态 -1:没有网络
* 1:WIFI网络2:wap网络3:net网络
* @param context
* @return
*/
public static int getAPNType(Context context) {
int netType = -1;
ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

if (networkInfo == null) {
return netType;
}
int nType = networkInfo.getType();
System.out.println("networkInfo.getExtraInfo() is "+ networkInfo.getExtraInfo());
if (nType == ConnectivityManager.TYPE_MOBILE) {
if (networkInfo.getExtraInfo().toLowerCase().equals("cmnet")) {
netType = CMNET;
} else {
netType = CMWAP;
}
} else if (nType == ConnectivityManager.TYPE_WIFI) {
netType = WIFI;
}
return netType;
}
}

posted @ 2012-05-18 15:58 johnny901114 阅读(39) 评论(0) 编辑

1.Drawable—>Bitmap

Resources res=getResources();
Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.sample_0);

2.Bitmap---->Drawable

Drawable drawable =new BitmapDrawable(bmp);

另外在网上搜了些,也不知到底谁是原创的,反正不是我

1、Drawable → Bitmap

public static Bitmap drawableToBitmap(Drawable drawable) {

       

        Bitmap bitmap = Bitmap.createBitmap(

                                        drawable.getIntrinsicWidth(),

                                        drawable.getIntrinsicHeight(),

                                        drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888

                                                        : Bitmap.Config.RGB_565);

        Canvas canvas = new Canvas(bitmap);

        //canvas.setBitmap(bitmap);

        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

        drawable.draw(canvas);

        return bitmap;

}

2、从资源中获取Bitmap
Resources res=getResources();

Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic);

3、Bitmap → byte[]
private byte[] Bitmap2Bytes(Bitmap bm){

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    bm.compress(Bitmap.CompressFormat.PNG, 100, baos);

    return baos.toByteArray();   }

4、 byte[] → Bitmap

   private Bitmap Bytes2Bimap(byte[] b){

                    if(b.length!=0){

                            return BitmapFactory.decodeByteArray(b, 0, b.length);

                    }

                    else {

                            return null;

                    }

          }

from http://hi.baidu.com/enjoysoup/blog/item/40a8da15a274ab70ca80c4b0.html

posted @ 2012-04-13 14:27 johnny901114 阅读(62) 评论(0) 编辑

在创建尺寸大的模拟器时,会现在没有了手机键盘,那么需要知道一系列的电脑键盘对应的操作 
Home键(小房子键) 
在键盘上映射的就是home键,这倒是很好记。 
Menu键 
用于打开菜单的按键,在键盘上映射的是F2键,PgUp键同样可以。另外,看英文原文的意思,貌似这个键在某些机型上会被设计为左软件(left softkey) 

Start键 
这个键在模拟器和G1真机上我都没有找到到底是哪个键。映射的是Shift+F2或PgDn,某些机型会被设计为右软键(right softkey)。 
Back键 
返回键,用户返回上一个UI或者退出当前程序。键盘上映射ESC键。 
Call/Dial键(电话键) 
接听来电或启动拨号面板,这是一部手机最基本的功能键。PC键盘映射为F3键。 
Hangup/Light Off键(挂机键) 
挂断电话或关闭背灯用。键盘映射F4键。 
Search键 
在提供了Search功能的应用里快速打开Search对话框,比如在Browser里可以快速打开地址搜索栏。键盘映射F5。 
Power Down键(关闭电源) 
对应模拟器左上边缘的电源按钮,不过似乎在模拟器上按这个键并没什么用处。键盘映射F7。 
Volume Up (增大音量) 
键盘映射Ctrl+F5,也可以使用小数字键盘的”+”键。 
Volume Down(减小音量) 
键盘映射Ctrl+F6,也可以使用小数字键盘的”-”键。 
Camera 键 
键盘映射Ctrl+F3。不过也许是我设置有问题,在模拟上用这个快捷键似乎没任何反应。 
Switch Screen Orientation (旋屏) 
旋转模拟器屏幕方向,键盘映射Ctrl+F11。这是非常有用和常用的快捷键,几乎所有应用都会受到屏幕方向带来的Layout变化困扰,在开发程序时候,一定要测试屏幕方向的兼容性。 
Cell Networking On/Off (手机网络开关) 
这里说的手机网络指的是GPRS/3G这种数据网络,并不影响GSM网络。对于编写基于网络应用的同学,这个快捷键非常有用,可以测试网络异常中断的情况。键盘映射F8 

Code Profiling 
不知此为何物-.-,快捷键F9。英文原文:F9 (only with -trace startup option) 

Fullscreen Mode (全屏模式) 
一个没什么用的鸡肋功能。也许对于测试画面比较精细的游戏能有点帮助。快捷键是大家喜闻乐见的Alt+Enter。 
Trackball mode (轨迹球模式) 
这是一个非常有用的功能,按F6之后,可以打开轨迹球模式,模拟器左上角会显示一个小轨迹球。通过鼠标移动,可以模拟轨迹球的转动。对于测试利用轨迹球操作的应用会非常方便。 
Trackball mode Temporaily (临时轨迹球模式) 
这个功能很有意思,如果你有比较短暂的使用轨迹球的操作,那么可以按住Delete键滑动鼠标。释放Delete键会自动结束轨迹球模式。 
四方向键和中心键 
对应键盘四方向键和Enter键,当然也可以用数字小键盘,KEYPAD_5对应中心键。 

posted @ 2012-04-06 09:19 johnny901114 阅读(19) 评论(0) 编辑

Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个java虚拟机。JAVA程序启动时JVM都会分配一个初始内存和最大内存给这个应用程序。这个初始内存和最大内存在一定程度都会影响程序的性能。比如说在应用程序用到最大内存的时候,JVM是要先去做垃圾回收的动作,释放被占用的一些内存。所以想调整Tomcat的启动时初始内存和最大内存就需要向JVM声明,一般的JAVA程序在运行都可以通过中-Xms -Xmx来调整应用程序的初始内存和最大内存: 
 这两个值的大小一般根据需要进行设置。初始化堆的大小执行了虚拟机在启动时向系统申请的内存的大小。一般而言,这个参数不重要。但是有的应用程序在大负载的情况下会急剧地占用更多的内存,此时这个参数就是显得非常重要,如果虚拟机启动时设置使用的内存比较小而在这种情况下有许多对象进行初始化,虚拟机就必须重复地增加内存来满足使用。由于这种原因,我们一般把-Xms和-Xmx设为一样大,而堆的最大值受限于系统使用的物理内存。一般使用数据量较大的应用程序会使用持久对象,内存使用有可能迅速地增长。当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃。因此一般建议堆的最大值设置为可用内存的最大值的80%。

     Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。有以下几种方法可以选用:

第一种方法:

  Windows下,在文件/bin/catalina.bat,Unix下,在文件/bin/catalina.sh的前面,增加如下设置:

  JAVA_OPTS=''-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】''

  需要把这个两个参数值调大。例如:

  JAVA_OPTS=''-Xms256m -Xmx512m''

  表示初始化内存为256MB,可以使用的最大内存为512MB。

第二种方法: 环境变量中设   
变量名:JAVA_OPTS   
变量值:-Xms512m   -Xmx512m


第三种方法:前两种方法针对的是bin目录下有catalina.bat的情况(比如直接解压的Tomcat等),但是有些安装版的Tomcat下没有catalina.bat,这个时候可以采用如下方法,当然这个方法也是最通用的方法:
打开tomcatHome/\bin/\tomcat5w.exe,点击Java选项卡,然后将会发现其中有这么两项:Initial memory pool和Maximum memory pool.Initial memory pool这个就是初始化设置的内存的大小。Maximum memory pool这个是最大内存的大小 设置完了就按确定然后再重启TOMCAT你就会发现tomcat中jvm可用的内存改变了

  另外需要考虑的是Java提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关,应该通过分析实际的垃圾收集的时间和频率来调整。如果堆的大小很大,那么完全垃圾收集就会很慢,但是频度会降低。如果你把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。在基准测试的时候,为保证最好的性能,要把堆的大小设大,保证垃圾收集不在整个基准测试的过程中出现。
   如果系统花费很多的时间收集垃圾,请减小堆大小。一次完全的垃圾收集应该不超过 3-5 秒。如果垃圾收集成为瓶颈,那么需要指定代的大小,检查垃圾收集的详细输出,研究 垃圾收集参数对性能的影响。一般说来,你应该使用物理内存的 80% 作为堆大小。当增加处理器时,记得增加内存,因为分配可以并行进行,而垃圾收集不是并行的。

一个要注意的地方:建议把内存的最高值跟最低值的差值缩小,不然会浪费很多内存的, 最低值加大 ,最高值可以随便设,但是要根据实际的物理内存 ,如果内存设置太大了,比如设置了512M最大内存,但如果没有512M可用内存,Tomcat就不能启动,还有可能存在内存被系统回收,终止进程的情况。

详细出处参考:http://www.itqun.net/content-detail/68572.html

posted @ 2012-02-24 15:58 johnny901114 阅读(20) 评论(0) 编辑
摘要: 1>比如滑动手指,界面切换.就可以使用ViewFlipper来实现ViewFlipper简单的使用:先在layout配置文件里面添加两个按钮和一个ViewFlipper控件 <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="pre" android:text="上一个" /> <阅读全文
posted @ 2012-02-19 20:23 johnny901114 阅读(127) 评论(0) 编辑
摘要: ,首先定义个工具类:/** * 异步的任务 ,接受的参数是 要下载图片的url * 返回值 是这个图片 的bitMap */public class LoadImageAsyncTask extends AsyncTask<String, Void, Bitmap> { // 定义一个接口 ,接口里面包含了几个需要实现的方法 // 谁调用 LoadImageAsyncTask 就必须实现这个接口里面定义的方法 private LoadImageCallback loadImageCallback; //因为LoadImageAsyncTask 没有默认的空参数的构造方法 pub..阅读全文
posted @ 2012-02-17 17:09 johnny901114 阅读(54) 评论(0) 编辑
摘要: 1,自定义title和Toasttitle :第一种方式:requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main);//只需要把main的layout文件中的控件的高度设置成类似于title一样的高度.第二种方式://google推荐的自定义title的做法 //1 .自定义title requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.m...阅读全文
posted @ 2012-02-14 14:49 johnny901114 阅读(11) 评论(0) 编辑
摘要: 1,程序锁2屏蔽后退键.1,程序锁就是用户把某个程序设置密码,当启动的时候需要输入密码或者其他凭证.1>首先我们要把系统中所有的程序都列出来.2>然后创建数据库,把需要锁定的程序的package添加到数据库.3>再通过contentProvider把数据的增删改查暴露给外部.4>新建一个程序,主要是提供服务的,不停的监视打开的程序,这是一个远程的服务,能够被上面的程序启动它的服务.5>通过内容观察者获取内容提供者提供的内容.如获取所有数据的方法.6>然后注册内容观察者,如果数据库发生改变,重新获取要锁定程序的集合,保证集合是最新的.前提是设置了通知(noti阅读全文
posted @ 2012-02-11 23:13 johnny901114 阅读(13) 评论(0) 编辑
摘要: 我们知道要访问服务里的方法必须要是绑定服务,bindService,而不是startService,他们俩的区别在这里就不赘述了.1,怎么访问本地服务里面的方法:首先我们来定义一个Servicepublic class LocalService extends Service { @Override public IBinder onBind(Intent intent) { return new MyBinder(); } public void serviceMethod() { Log.i("LocalService", "我是服务里面的方法");阅读全文
posted @ 2012-02-10 23:23 johnny901114 阅读(96) 评论(0) 编辑