Submitted by admin on 2011, June 30, 4:00 PM
google于2007年底正式发布了Android SDK, 作为 Android系统的重要特性,Dalvik虚拟机也第一次进入了人们的视野。它对内存的高效使用,和在低速CPU上表现出的高性能,确实令人刮目相看。依赖于底层Posix兼容的操作系统,它可以简单的完成进程隔离和线程管理。每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。
很多人认为Dalvik虚拟机是一个Java虚拟机,因为Android的编程语言恰恰就是Java语言。但是这种说法并不准确,因为Dalvik虚拟机并不是按照Java虚拟机的规范来实现的,两者并不兼容;同时还要两个明显的不同:
Java虚拟机运行的是Java字节码,而Dalvik虚拟机运行的则是其专有的文件格式DEX(Dalvik Executable)。
在Java SE程序中的Java类会被编译成一个或者多个字节码文件(.class)然后打包到JAR文件,而后Java虚拟机会从相应的CLASS文件和JAR文件中获取相应的字节码;Android应用虽然也是使用Java语言进行编程,但是在编译成CLASS文件后,还会通过一个工具(dx)将应用所有的CLASS文件转换成一个DEX文件,而后Dalvik虚拟机会从其中读取指令和数据
android | 评论:0
| Trackbacks:0
| 阅读:989
Submitted by admin on 2011, June 30, 1:10 PM
对于关注Android底层的朋友来说,其具体的启动过程应该是比较吸引我们的。但是很多启动文件什么的,都得adb push到host上来看,挺不方便的,都怪Android自带的Toolbox太简略了。所以在深入了解Android的启动流程之前,我们来把 Busybox安装到Android上去,这样,就有很多工具供我们使用了。
首先去busybox主页 下载最新版本的源代码,然后用arm的交叉编译器编译出busybox的可执行程序,编译的时候需要注意一些设置选项,例如
Build Options --->
Build BusyBox as a static binary (no shared libs) 这个要选上,因上这样子编译出来的busyBox才是可以独立运行的。
│ Do you want to build BusyBox with a Cross Compiler? │ │
│ │(/HOME/toolchains/gcc-4.0.2-glibc-2.3.5/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu│ 这是交叉编译器的路径,要根据具体的情况来设置。
Installation Options --->
Don't use /usr
这样子编译出来的busybox才不会安装到你主机的/usr目录下。一定要选上。
busybox的功能选项根据需要自选,但是不要太贪心.
OK,这里就不纠缠于编译busybox的东西了,网上资料无数。接下来,我们把busybox安装到模拟器上去。先在模拟器上随便建一个busybox的文件夹,然后进入busybox可执行文件目录,使用命令
adb push busybox.asc /data/busybox/busybox
然后进入adb shell,chmod 777 ./busybox,就可以直接使用了。但现在还是不方便,总不能每用一个命令就输一次busybox吧?所以,我们可以先用./busybox --install将程序都安装到当前目录下,然后把当前目录添加到PATH变量中即可。暂时使用export来添加吧,如果想永久添加,往下看。
好了,准备工作完成,开始研究的工作了。既然是研究启动过程,那当然是先看看init.rc文件。去etc目录打开它,分析一下内容,首先是对env的定义,也就是全局环境变量的定义,接下来的建立和初始化里面的内容目前还不清楚什么意思,紧接着就是系统启动时运行的初始进程信息,这个比较有意思,包括了 usbd-config和qemu,qemu自不用说,而usbd-config作为初始启动的进程,应该就是和上一篇文章猜的一样,用来调试或者usb 通信的。往下看,是在初始启动进程完成之后开始启动的服务进程,这些进程如果因故退出,会自动重启。这里面包括了console控制台,adbd监护进程,usbd监护进程,debuggerd监护进程等.除去这些守护进程,能引起我们注意的,是runtime和zygote。这两个进程似乎掌管着其他进程以及应用程序的启动。
现在,来让我们做一个实验吧,将自动调用的启动过程变成手动,看看启动流程具体是什么样的。想达到这个目的,首先就是要修改init.rc文件,当然不是在模拟器的console中改,一是不能改,二是你改了也没用,下次加载就会给你覆盖了。所以,我们要从原始镜像ramdisk.img入手了。从2.6标准Linux内核开始,initrd.img都采用cpio压缩,猜测ramdisk.img也一样,需要使用gunzip解压缩,然后再使用cpio解包。好,进入tools/lib/images目录下,先用file命令看看ramdisk.img的类型,没错,系统提示
ramdisk.img: gzip compressed data, from Unix
很好,然后将ramdisk.img复制一份到任何其他目录下,将其名称改为ramdisk.img.gz,并使用命令
gunzip ramdisk.img.gz
然后新建一个文件夹,叫ramdisk吧,进入,输入命令
cpio -i -F ../ramdisk.img
这下,你就能看见并操作ramdisk里面的内容了。当然你也可以直接在外面进行操作,但是还是建议把cpio解压缩出来的内容全部集中在一个文件夹里面,因为一会我们还要将其压缩成新的ramdisk.img。
OK,现在开始修改步骤吧。用任何一款编辑器打开init.rc,首先在PATH那里加上你的Busybox安装路径,然后注释内容,我们要手工启动他们。
# zygote {
# exec /system/bin/app_process
# args {
# 0 -Xzygote
# 1 /system/bin
# 2 --zygote
# }
# autostart 1
# }
# runtime {
# exec /system/bin/runtime
# autostart 1
# }
在这里需要注意,不要同时把两者都注释了,注释某一个,再试验手工启动它,如果两者同时注释我这里有问题,无法启动。
好,接下来,使用下列命令重新打包成镜像
cpio -i -t -F ../ramdisk.img > list
cpio -o -H newc -O lk.img < list
当前目录下生成的lk.img就是我们的新镜像了。使用自己的镜像启动emulator;
emulator -console -ramdisk lk.img
如果我们注释的是zygote,那么在#后输入
app_process -Xzygote /system/bin --zygote
手工启动,命令行中输出的信息是
Prepping: /system/app/AlarmProvider.apk:/system/app/Browser.apk:/system/app/Calendar.apk:/system/app/Camera.apk:/system/app/Contacts.apk:
/system/app/Development.apk:/system/app/GDataFeedsProvider.apk:/system/app/Gmail.apk:/system/app/GmailProvider.apk:/system/app/GoogleApps.apk:
/system/app/GoogleAppsProvider.apk:/system/app/Home.apk:/system/app/ImProvider.apk:/system/app/Maps.apk:/system/app/MediaPickerActivity.apk:
/system/app/MediaProvider.apk:/system/app/Phone.apk:/system/app/PimProvider.apk:/system/app/ApiDemos.apk:/system/app/SettingsProvider.apk:
/system/app/Sms.apk:/system/app/SyncProvider.apk:/system/app/TelephonyProvider.apk:/system/app/XmppService.apk:/system/app/YouTube.apk
File not found: /system/app/AlarmProvider.apk
File not found: /system/app/Calendar.apk
File not found: /system/app/Camera.apk
File not found: /system/app/GDataFeedsProvider.apk
File not found: /system/app/Gmail.apk
File not found: /system/app/GmailProvider.apk
File not found: /system/app/MediaPickerActivity.apk
File not found: /system/app/PimProvider.apk
File not found: /system/app/ApiDemos.apk
File not found: /system/app/Sms.apk
File not found: /system/app/SyncProvider.apk
File not found: /system/app/YouTube.apk
Prep complete
嘿嘿,从File not found的信息中可以看到一些Google可能会即将推出的应用,比如Gmail什么的。
如果我们注释的是runtime,那么输出信息是:
+++ post-zygote
老实说,没有明白这是啥意思,呵呵。
好了,今天就说到这,基本的方法就是这样,有兴趣的朋友可以进一步深入研究。我们下一篇文章见。时间上的老鸟
转
android | 评论:0
| Trackbacks:0
| 阅读:987
Submitted by admin on 2011, June 30, 1:08 PM
Android屏幕禁止休眠的方法 实现这一功能的方法有两种,一种是在Manifest.xml文件里面声明,一种是在代码里面修改LayoutParams的标志位。具体如下:
1、在Manifest.xml文件里面用user-permission声明。代码如下:
-
- [post] <uses-permission android:name="android.permission.WAKE_LOCK">
- </uses-permission>[/post]
这种方法,在安装apk时,系统会提示安装人是否允许使用禁止休眠功能。
2、在程序中用代码实现。代码如下:
本部分设定了隐藏,您已回复过了,以下是隐藏的内容
-
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
把这段代码加在setContentView(R.layout.main)之前即可
android | 评论:0
| Trackbacks:0
| 阅读:1128
Submitted by admin on 2011, June 30, 11:10 AM
我们曾就《Android手势识别ViewFlipper触摸动画》做过详细的讲解,其实,Android应用程序开发中,多点触摸(Multitouch)不是那么遥不可及,实现起来也很简单。如果您对开发多点触摸程序感兴趣的话,那么本文将是一个很好的开始,本例只需要两个类就能实现多点触摸。
首先来看看我们的视图类MTView.java:
- package com.ideasandroid.demo;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.view.MotionEvent;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
-
- public class MTView extends SurfaceView implements SurfaceHolder.Callback {
-
- private static final int MAX_TOUCHPOINTS = 10;
- private static final String START_TEXT = "请随便触摸屏幕进行测试";
- private Paint textPaint = new Paint();
- private Paint touchPaints[] = new Paint[MAX_TOUCHPOINTS];
- private int colors[] = new int[MAX_TOUCHPOINTS];
-
- private int width, height;
- private float scale = 1.0f;
-
- public MTView(Context context) {
- super(context);
- SurfaceHolder holder = getHolder();
- holder.addCallback(this);
- setFocusable(true); // 确保我们的View能获得输入焦点
- setFocusableInTouchMode(true); // 确保能接收到触屏事件
- init();
- }
-
- private void init() {
- // 初始化10个不同颜色的画笔
- textPaint.setColor(Color.WHITE);
- colors[0] = Color.BLUE;
- colors[1] = Color.RED;
- colors[2] = Color.GREEN;
- colors[3] = Color.YELLOW;
- colors[4] = Color.CYAN;
- colors[5] = Color.MAGENTA;
- colors[6] = Color.DKGRAY;
- colors[7] = Color.WHITE;
- colors[8] = Color.LTGRAY;
- colors[9] = Color.GRAY;
- for (int i = 0; i < MAX_TOUCHPOINTS; i++) {
- touchPaints[i] = new Paint();
- touchPaints[i].setColor(colors[i]);
- }
- }
-
- /*
- * 处理触屏事件
- */
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- // 获得屏幕触点数量
- int pointerCount = event.getPointerCount();
- if (pointerCount > MAX_TOUCHPOINTS) {
- pointerCount = MAX_TOUCHPOINTS;
- }
- // 锁定Canvas,开始进行相应的界面处理
- Canvas c = getHolder().lockCanvas();
- if (c != null) {
- c.drawColor(Color.BLACK);
- if (event.getAction() == MotionEvent.ACTION_UP) {
- // 当手离开屏幕时,清屏
- } else {
- // 先在屏幕上画一个十字,然后画一个圆
- for (int i = 0; i < pointerCount; i++) {
- // 获取一个触点的坐标,然后开始绘制
- int id = event.getPointerId(i);
- int x = (int) event.getX(i);
- int y = (int) event.getY(i);
- drawCrosshairsAndText(x, y, touchPaints[id], i, id, c);
- }
- for (int i = 0; i < pointerCount; i++) {
- int id = event.getPointerId(i);
- int x = (int) event.getX(i);
- int y = (int) event.getY(i);
- drawCircle(x, y, touchPaints[id], c);
- }
- }
- // 画完后,unlock
- getHolder().unlockCanvasAndPost(c);
- }
- return true;
- }
-
- /**
- * 画十字及坐标信息
- *
- * @param x
- * @param y
- * @param paint
- * @param ptr
- * @param id
- * @param c
- */
- private void drawCrosshairsAndText(int x, int y, Paint paint, int ptr,
- int id, Canvas c) {
- c.drawLine(0, y, width, y, paint);
- c.drawLine(x, 0, x, height, paint);
- int textY = (int) ((15 + 20 * ptr) * scale);
- c.drawText("x" + ptr + "=" + x, 10 * scale, textY,
- c.drawText("y" + ptr + "=" + y, 70 * scale, textY,
- c.drawText("id" + ptr + "=" + id, width - 55 * sc
- }
-
- /**
- * 画圆
- *
- * @param x
- * @param y
- * @param paint
- * @param c
- */
- private void drawCircle(int x, int y, Paint paint, Canvas c
- c.drawCircle(x, y, 40 * scale, paint);
- }
-
- /*
- * 进入程序时背景画成黑色,然后把“START_TEXT”写到屏幕
- */
- public void surfaceChanged(SurfaceHolder holder, int format, i
- int height) {
- this.width = width;
- this.height = height;
- if (width > height) {
- this.scale = width / 480f;
- } else {
- this.scale = height / 480f;
- }
- textPaint.setTextSize(14 * scale);
- Canvas c = getHolder().lockCanvas();
- if (c != null) {
- // 背景黑色
- c.drawColor(Color.BLACK);
- float tWidth = textPaint.measureText(START_TEXT);
- c.drawText(START_TEXT, width / 2 - tWidth / 2
- textPaint);
- getHolder().unlockCanvasAndPost(c);
- }
- }
-
- public void surfaceCreated(SurfaceHolder holder) {
- }
-
- public void surfaceDestroyed(SurfaceHolder holder) {
- }
-
- }
接下来看看我们的Activity,MultitouchVisible.java
- package com.ideasandroid.demo;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Window;
- import android.view.WindowManager;
-
- public class MultitouchVisible extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //隐藏标题栏
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- //设置成全屏
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- //设置为上面的MTView
- setContentView(new MTView(this));
- }
- }
android | 评论:0
| Trackbacks:0
| 阅读:1048
Submitted by admin on 2011, June 29, 4:03 PM
cat .htaccess
RewriteEngine on
RewriteRule ^(.*)$ http://www.51099.com/$1 [R=301,L]
----------------
vhost
RewriteEngine on
RewriteCond %{HTTP_HOST} ^51099.com$ [NC]
RewriteRule ^(.*)$ http://www.51099.com$1 [R=301,L]
apache/web | 评论:0
| Trackbacks:0
| 阅读:1068
Submitted by admin on 2011, June 29, 4:00 PM
不使用压缩:
curl http://www.yoursite.com --silent --write-out "size_download=%{size_download}\n" --output /dev/null
size_download=64031
使用 Accept-Encoding 头:
curl http://www.yoursite.com --silent -H "Accept-Encoding: gzip,deflate" --write-out "size_download=%{size_download}\n" --output /dev/null
size_download=20012
比较数字就可以知道压缩效果。
使用 HTTP 1.0 测试:
curl http://www.yoursite.com --silent --http1.0 -H "Accept-Encoding: gzip,deflate" --write-out "size_download=%{size_download}\n" --output /dev/null
size_download=64031
http | 评论:0
| Trackbacks:0
| 阅读:1095
Submitted by admin on 2011, June 29, 3:58 PM
我们老是打开网页上网,但是都没有注意到页面发我们的到底是什么样子的数据呢?下面我就详细的介绍给大家。
1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。
2. Accept-Charset: 浏览器申明自己接收的字符集
Accept-Encoding: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)
Accept-Language::浏览器申明自己接收的语言
语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等。
3. Accept-Ranges:WEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。
bytes:表示接受,none:表示不接受。
4. Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。
5. Authorization:当客户端接收到来自WEB服务器的 WWW-Authenticate 响应时,用该头部来回应自己的身份验证信息给WEB服务器。
6. Cache-Control:请求:no-cache(不要缓存的实体,要求现在从WEB服务器去取)
max-age:(只接受 Age 值小于 max-age 值,并且没有过期的对象)
max-stale:(可以接受过去的对象,但是过期时间必须小于 max-stale 值)
min-fresh:(接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象)
响应:public(可以用 Cached 内容回应任何用户)
private(只能用缓存内容回应先前请求该内容的那个用户)
no-cache(可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端)
max-age:(本响应包含的对象的过期时间)
ALL: no-store(不允许缓存)
7. Connection:请求:close(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了)。
keepalive(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求)。
响应:close(连接已经关闭)。
keepalive(连接保持着,在等待本次连接的后续请求)。
Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持连接多长时间(秒)。
例如:Keep-Alive:300
8. Content-Encoding:WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。
例如:Content-Encoding:gzip
Content-Language:WEB 服务器告诉浏览器自己响应的对象的语言。
Content-Length: WEB 服务器告诉浏览器自己响应的对象的长度。
例如:Content-Length: 26012
Content-Range: WEB 服务器表明该响应包含的部分对象为整个对象的哪个部分。
例如:Content-Range: bytes 21010-47021/47022
Content-Type: WEB 服务器告诉浏览器自己响应的对象的类型。
例如:Content-Type:application/xml
9. ETag:就是一个对象(比如URL)的标志值,就一个对象而言,比如一个 html 文件,如果被修改了,其 Etag 也会别修改,
所以,ETag 的作用跟 Last-Modified 的作用差不多,主要供 WEB 服务器判断一个对象是否改变了。
比如前一次请求某个 html 文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得的 ETag 值发送给
WEB 服务器,然后 WEB 服务器会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件有没有改变了。
10. Expired:WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟WEB服务器验证了其有效性后,才能用来响应客户请求。
是 HTTP/1.0 的头部。
例如:Expires:Sat, 23 May 2009 10:02:12 GMT
11. Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号。
例如:Host:rss.sina.com.cn
12. If-Match:如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作。
If-None-Match:如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作。
13. If-Modified-Since:如果请求的对象在该头部指定的时间之后修改了,才执行请求的动作(比如返回对象),否则返回代码304,告诉浏览器该对象没有修改。
例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT
If-Unmodified-Since:如果请求的对象在该头部指定的时间之后没修改过,才执行请求的动作(比如返回对象)。
14. If-Range:浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,如果对象改变了,就把整个对象给我。
浏览器通过发送请求对象的 ETag 或者 自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。
总是跟 Range 头部一起使用。
15. Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。
例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT
16. Location:WEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了,到该头部指定的位置去取。
例如:Location:http://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif
17. Pramga:主要使用 Pramga: no-cache,相当于 Cache-Control: no-cache。
例如:Pragma:no-cache
18. Proxy-Authenticate: 代理服务器响应浏览器,要求其提供代理身份验证信息。
Proxy-Authorization:浏览器响应代理服务器的身份验证请求,提供自己的身份信息。
19. Range:浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。
例如:Range: bytes=1173546-
20. Referer:浏览器向 WEB 服务器表明自己是从哪个 网页/URL 获得/点击 当前请求中的网址/URL。
例如:Referer:http://www.sina.com/
21. Server: WEB 服务器表明自己是什么软件及版本等信息。
例如:Server:Apache/2.0.61 (Unix)
22. User-Agent: 浏览器表明自己的身份(是哪种浏览器)。
例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14
23. Transfer-Encoding: WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)作了怎样的编码,比如是否分块(chunked)。
例如:Transfer-Encoding: chunked
24. Vary: WEB服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应所返回的对象响应后续的请求。
假如源WEB服务器在接到第一个请求消息时,其响应消息的头部为:Content-Encoding: gzip; Vary: Content-Encoding
那么 Cache 服务器会分析后续请求消息的头部,检查其 Accept-Encoding,是否跟先前响应的 Vary 头部值一致,即是否使用
相同的内容编码方法,这样就可以防止 Cache 服务器用自己 Cache 里面压缩后的实体响应给不具备解压能力的浏览器。
例如:Vary:Accept-Encoding
25. Via: 列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用什么协议(和版本)发送的请求。
当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面添加 Via 头部,并填上自己的相关信息,当下一个代理服务器
收到第一个代理服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via 头部,并把自己的相关信息加到后面,
以此类推,当 OCS 收到最后一个代理服务器的请求时,检查 Via 头部,就知道该请求所经过的路由。
例如:Via:1.0 236-81.D07071953.sina.com.cn:80 (squid/2.6.STABLE13)
============================================================================================================================
HTTP 请求消息头部实例:
Host:rss.sina.com.cn
User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14
Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language:zh-cn,zh;q=0.5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive:300
Connection:keep-alive
Cookie:userId=C5bYpXrimdmsiQmsBPnE1Vn8ZQmdWSm3WRlEB3vRwTnRtW <-- Cookie
If-Modified-Since:Sun, 01 Jun 2008 12:05:30 GMT
Cache-Control:max-age=0
HTTP 响应消息头部实例:
Status:OK - 200 <-- 响应状态码,表示 web 服务器处理的结果。
Date:Sun, 01 Jun 2008 12:35:47 GMT
Server:Apache/2.0.61 (Unix)
Last-Modified:Sun, 01 Jun 2008 12:35:30 GMT
Accept-Ranges:bytes
Content-Length:18616
Cache-Control:max-age=120
Expires:Sun, 01 Jun 2008 12:37:47 GMT
Content-Type:application/xml
Age:2
X-Cache:HIT from 236-41.D07071951.sina.com.cn <-- 反向代理服务器使用的 HTTP 头部
Via:1.0 236-41.D07071951.sina.com.cn:80 (squid/2.6.STABLE13)
Connection:close
http | 评论:0
| Trackbacks:0
| 阅读:1179
Submitted by admin on 2011, June 29, 3:51 PM
cpu速度越来越快也更便宜,IDC机房带宽很昂贵,所以用cpu来换取带宽。
apche启用mod_deflate压缩:
<ifmodule mod_deflate.c>
DeflateCompressionLevel 9
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</ifmodule>
nginx 启用gzip压缩:
http {
gzip on;
gzip_min_length 1000;
gzip_buffers 4 8k;
gzip_types text/plain application/x-javascript text/css text/html application/xml;
}
压缩效果测试
不使用压缩:
curl http://veryi.com/w/1.html –silent –write-out "size_download=%{size_download}\n" –output /dev/null
size_download=64031
使用 Accept-Encoding 头:
curl http://veryi.com/w/1.html –silent -H "Accept-Encoding: gzip,deflate" –write-out "size_download=%{size_download}\n" –output /dev/null
size_download=20012
比较数字就可以知道压缩效果。
使用 HTTP 1.0 测试:
curl http://veryi.com/w/1.html –silent –http1.0 -H "Accept-Encoding: gzip,deflate" –write-out "size_download=%{size_download}\n" –output /dev/null
size_download=64031
参考:http://dev.nuclearrooster.com/2009/11/08/checking-gzipdeflate-server-responses-with-curl/
转
apache/web | 评论:0
| Trackbacks:0
| 阅读:1189