如何解决css3动画卡顿在安卓机上卡顿现象

后使用快捷导航没有帐号?
只需一步,快速开始
查看: 1025|回复: 9
在线时间13 小时经验值256 最后登录注册时间帖子阅读权限50UID4712981
大学专科, 积分 256, 距离下一级还需 144 积分
TA的每日心情开心 17:01签到天数: 1 天[LV.1]初来乍到
G币4 最后登录注册时间
马上注册,结交更多机友,下载更多应用,让你轻松玩转手机。
已有帐号?   下载游戏和软件,请【】进入机锋市场!
如题,本人将去年年初购买的白色国行G2给了老婆,于今年2月中旬花了 3179元人民币入手某东的D857(钛金黑),新机一到手,拆开后盖后放入闲置已久的8G内存卡一张(主要由于内存卡上有许多重要资料),开机后,本人便极度后悔入手G3。原因就在:整个UI系统居然没有G2顺畅,会延迟、卡顿。后来也根据论坛里的机油们提供的建议,采取了一系列的如关闭动画,限制后台进程等一系列措施,一切均无果。后来听说上了5.0后会有改善,但是目前国际版的857好像还没推送OTA升级包....... 总之很失落。(本人不想刷机,本人以前使用戴妃后渐渐明白,刷机这事根本就停不下来)。
但是,就在昨晚,因不能忍受图片库里某些SD卡里的图片预览时会有SD卡的标志,便整理SD卡资料后,把内存卡拔出,不再使用(G3本身自带的内存对我来说也基本上够用了),重启后发现,居然没有卡顿及延迟的现象了。&&我试了一个软件“京东手机端软件”,在插内存卡的时候,此软件下滑页面使延迟卡顿现象相当严重,但是在拔出内存卡后居然得到了极大的改善,至少跟先前使用的G2一样顺滑了。&&到目前只是发现图片库里大点的图片载入使,居然会出现“正在载入”的字样,感觉不给力的样子......(G2没有这种情况)
本人是小白,不知是不是因为内存卡容量太小才导致G3延迟卡顿,还是因为只要插内存卡就会致使G3延迟卡顿。总之我的G3现在顺滑了很多。&&特及时跟大家分享,不知能帮到多少机油。
在线时间0 小时经验值357 最后登录注册时间帖子阅读权限50UID
大学专科, 积分 357, 距离下一级还需 43 积分
TA的每日心情奋斗 06:32签到天数: 63 天[LV.6]常住居民II
G币153 最后登录注册时间
卡本身的速度低了
在线时间88 小时经验值825 最后登录注册时间帖子阅读权限70UID
学士, 积分 825, 距离下一级还需 275 积分
TA的每日心情奋斗 15:53签到天数: 3 天[LV.2]偶尔看看I
G币3 最后登录注册时间
不用内存卡也能卡死,你那种情况我估计内存卡都是c4级别以下的
在线时间13 小时经验值256 最后登录注册时间帖子阅读权限50UID4712981
大学专科, 积分 256, 距离下一级还需 144 积分
TA的每日心情开心 17:01签到天数: 1 天[LV.1]初来乍到
G币4 最后登录注册时间
schodt 发表于
不用内存卡也能卡死,你那种情况我估计内存卡都是c4级别以下的
G2使用一年多了,从来没有死机过。G3只用了半个月,目前倒是未遇到过死机。之前的内存卡容量确实低,速度嘛,估计也已一定很慢。
在线时间0 小时经验值79 最后登录注册时间帖子阅读权限30UID230479
初中生, 积分 79, 距离下一级还需 21 积分
TA的每日心情开心 13:40签到天数: 10 天[LV.3]偶尔看看II
G币26 最后登录注册时间
这样呀,呼啦啦
在线时间83 小时经验值123 最后登录注册时间帖子阅读权限1UID7536
头像被屏蔽
TA的每日心情慵懒 00:10签到天数: 2 天[LV.1]初来乍到
G币37 最后登录注册时间
提示: 作者被禁止或删除 内容自动屏蔽
在线时间989 小时经验值1072 最后登录注册时间帖子阅读权限70UID87016
学士, 积分 1072, 距离下一级还需 28 积分
TA的每日心情擦汗 19:39签到天数: 2 天[LV.1]初来乍到
G币116 最后登录注册时间
&&试了 确实有用 我以前用建行手机银行卡的完全不能用& &把内存卡取了&&就正常了&&我的是C10的内存卡&&
在这个世界上,总是看你2的人很多,陪你2的人很少。。
在线时间1 小时经验值1681 最后登录注册时间帖子阅读权限80UID
研究生, 积分 1681, 距离下一级还需 19 积分
TA的每日心情郁闷 19:06签到天数: 2 天[LV.1]初来乍到
G币2 最后登录注册时间
难道我要把花了几大百买的64G的内存卡拔了?话说拔了也没见流畅
在线时间880 小时经验值3807 最后登录注册时间帖子阅读权限110UID791769
博士后, 积分 3807, 距离下一级还需 893 积分
TA的每日心情郁闷 00:44签到天数: 4 天[LV.2]偶尔看看I
G币163 最后登录注册时间
G3用到现在没用过内存卡,但感觉流畅程度和NEXUS5完全是好几个档次
V220→MPX220→E2→ZN5→Q11→D2g
K508→3220→D900→902SH→G1
→D908→HD2→8310→Z1i→i917
→→V880→U812→9250
→8s→SH01a→9930→D859→S7e
在线时间1920 小时经验值4440 最后登录注册时间帖子阅读权限110UID11768
博士后, 积分 4440, 距离下一级还需 260 积分
TA的每日心情奋斗 09:07签到天数: 18 天[LV.4]偶尔看看III
G币995 最后登录注册时间
我没觉得卡顿过啊,至少拨号没觉得卡过
Powered by2015年7月 Web 开发大版内专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。低版本android(4.0)运行css3 transition动画较流畅,而4.3+上执行较慢,并且出现卡顿。_问答_ThinkSAAS
低版本android(4.0)运行css3 transition动画较流畅,而4.3+上执行较慢,并且出现卡顿。
低版本android(4.0)运行css3 transition动画较流畅,而4.3+上执行较慢,并且出现卡顿。
低版本android(4.0)运行css3 transition动画较流畅,而4.3+上执行较慢,并且出现卡顿。请问是不是需要对webview做些什么设置?是否因为没有开启GPU渲染?
添加你想要问的问题
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信Android学习分享:执行某ViewGroup的动画时,子控件太多导致动画执行卡顿的问题-爱编程
Android学习分享:执行某ViewGroup的动画时,子控件太多导致动画执行卡顿的问题
最近在项目中遇到一个问题,我有一个LinearLayout,里面装载了许多ImageView控件,ImageView控件显示着自己的图片,这个LinearLayout支持双指缩放,缩放采用ScaleAnimation来实现,但是但是在缩放过程中,屏幕十分卡顿,缩放效果根本没有跟上手指的缩放动作。后来在Google上查了一番,查到一个API,叫setAnimationDrawCacheEnabled(boolean enabled):
* Enables or disables the children's drawing cache during a layout animation.
* By default, the drawing cache is enabled but this will prevent nested
* layout animations from working. To nest animations, you must disable the
* @param enabled true to enable the animation cache, false otherwise
* @see #isAnimationCacheEnabled()
* @see View#setDrawingCacheEnabled(boolean)
public void setAnimationCacheEnabled(boolean enabled) {
setBooleanFlag(FLAG_ANIMATION_CACHE, enabled);
方法的注解我这里简单翻译一下:在执行一个Layout动画时开启或关闭子控件的绘制缓存。默认情况下,绘制缓存是开启的,但是这将阻止嵌套Layout动画的正常执行。对于嵌套动画,你必须禁用这个缓存。
先说drawing cache,绘制缓存的概念,Android为了提高View视图的绘制效率,提出了一个缓存的概念,其实就是一个Bitmap,用来存储View当前的绘制内容,在View的内容或者尺寸未发生改变时,这个缓存应该始终不被销毁,销毁了如果下次还用(开启了绘图缓存的前提下,API为setDrawingCacheEnabled(enabled),另外还可以设置绘图缓存Bitmap的质量,API为setDrawingCacheQuality(quality))就必须重建。
关于绘图缓存的相关介绍,可搜索这些相关API的介绍:
1)setDrawingCacheQuality(int quality)
2)setDrawingCacheEnabled(enabled)
3)setDrawingCacheBackgroundColor(color)
先看一段代码:
* &p&Forces the drawing cache to be built if the drawing cache is invalid.&/p&
* &p&If you call {@link #buildDrawingCache()} manually without calling
* {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
* should cleanup the cache by calling {@link #destroyDrawingCache()} afterwards.&/p&
* &p&Note about auto scaling in compatibility mode: When auto scaling is not enabled,
* this method will create a bitmap of the same size as this view. Because this bitmap
* will be drawn scaled by the parent ViewGroup, the result on screen might show
* scaling artifacts. To avoid such artifacts, you should call this method by setting
* the auto scaling to true. Doing so, however, will generate a bitmap of a different
* size than the view. This implies that your application must be able to handle this
* size.&/p&
* &p&You should avoid calling this method when hardware acceleration is enabled. If
* you do not need the drawing cache bitmap, calling this method will increase memory
* usage and cause the view to be rendered in software once, thus negatively impacting
* performance.&/p&
* @see #getDrawingCache()
* @see #destroyDrawingCache()
public void buildDrawingCache(boolean autoScale) {
if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
mDrawingCache == null : mUnscaledDrawingCache == null)) {
mCachingFailed = false;
int width = mRight - mL
int height = mBottom - mT
final AttachInfo attachInfo = mAttachI
final boolean scalingRequired = attachInfo != null && attachInfo.mScalingR
if (autoScale && scalingRequired) {
width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
final int drawingCacheBackgroundColor = mDrawingCacheBackgroundC       // 1.这里
final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingC
final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
final long drawingCacheSize =
ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
if (width &= 0 || height &= 0 || projectedBitmapSize & drawingCacheSize) {
if (width & 0 && height & 0) {
Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs "
+ projectedBitmapSize + " bytes, only "
+ drawingCacheSize + " available");
destroyDrawingCache();
mCachingFailed = true;
boolean clear = true;
Bitmap bitmap = autoScale ? mDrawingCache : mUnscaledDrawingC
if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
Bitmap.C          // 2.这里
if (!opaque) {
// Never pick ARGB_4444 because it looks awful
// Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
case DRAWING_CACHE_QUALITY_AUTO:
case DRAWING_CACHE_QUALITY_LOW:
case DRAWING_CACHE_QUALITY_HIGH:
quality = Bitmap.Config.ARGB_8888;
// Optimization for translucent windows
// If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
quality = use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
// Try to cleanup memory
if (bitmap != null) bitmap.recycle();
bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
width, height, quality);
bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
if (autoScale) {
mDrawingCache =
mUnscaledDrawingCache =
if (opaque && use32BitCache) bitmap.setHasAlpha(false);
} catch (OutOfMemoryError e) {
// If there is not enough memory to create the bitmap cache, just
// ignore the issue as bitmap caches are not required to draw the
// view hierarchy
if (autoScale) {
mDrawingCache = null;
mUnscaledDrawingCache = null;
mCachingFailed = true;
clear = drawingCacheBackgroundColor != 0;
if (attachInfo != null) {
canvas = attachInfo.mC
if (canvas == null) {
canvas = new Canvas();
canvas.setBitmap(bitmap);
// Temporarily clobber the cached Canvas in case one of our children
// is also using a drawing cache. Without this, the children would
// steal the canvas by attaching their own bitmap to it and bad, bad
// thing would happen (invisible views, corrupted drawings, etc.)
attachInfo.mCanvas = null;
// This case should hopefully never or seldom happen
canvas = new Canvas(bitmap);
if (clear) {
bitmap.eraseColor(drawingCacheBackgroundColor);
computeScroll();
final int restoreCount = canvas.save();
if (autoScale && scalingRequired) {
final float scale = attachInfo.mApplicationS
canvas.scale(scale, scale);
canvas.translate(-mScrollX, -mScrollY);
mPrivateFlags |= PFLAG_DRAWN;
if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
mLayerType != LAYER_TYPE_NONE) {
mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID;
// Fast path for layouts with no backgrounds
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
dispatchDraw(canvas);
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().draw(canvas);
draw(canvas);
canvas.restoreToCount(restoreCount);
canvas.setBitmap(null);
if (attachInfo != null) {
// Restore the cached Canvas for our siblings
attachInfo.mCanvas =
两个标注了红色的地方,说明了这个mDrawingCacheBackgroundColor变量的作用,因此如果使用默认值,那么缓存Bitmap使用的是Bitmap.Config.ARGB_8888,比Bitmap.Config.RGB_565多占用了一半的内存,因此如果不想使用太大的内存,担心内存泄露,可以设置给mDrawingCacheBackgroundColor一个值,例如:
setDrawingCacheBackgroundColor(0xFF0C0C0C);
那么,那么,这个绘图缓存如何优化绘图速率,又怎么阻碍了Animation的执行?
先看两个方法:
1)ViewGroup -& dispatchDraw(Canvas canvas) 方法:
* {@inheritDoc}
protected void dispatchDraw(Canvas canvas) {
final int count = mChildrenC
final View[] children = mC
int flags = mGroupF
     // 关键字:FLAG_RUN_ANIMATION,FLAG_ANIMATION_CACHE,cache,buildCache
if ((flags & FLAG_RUN_ANIMATION) != 0 && canAnimate()) {
final boolean cache = (mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE;
final boolean buildCache = !isHardwareAccelerated();
for (int i = 0; i & i++) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
final LayoutParams params = child.getLayoutParams();
attachLayoutAnimationParameters(child, params, i, count);
bindLayoutAnimation(child);
if (cache) {
child.setDrawingCacheEnabled(true);
if (buildCache) {
child.buildDrawingCache(true);
final LayoutAnimationController controller = mLayoutAnimationC
if (controller.willOverlap()) {
mGroupFlags |= FLAG_OPTIMIZE_INVALIDATE;
controller.start();
mGroupFlags &= ~FLAG_RUN_ANIMATION;
mGroupFlags &= ~FLAG_ANIMATION_DONE;
if (cache) {
mGroupFlags |= FLAG_CHILDREN_DRAWN_WITH_CACHE;
if (mAnimationListener != null) {
mAnimationListener.onAnimationStart(controller.getAnimation());
int saveCount = 0;
final boolean clipToPadding = (flags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
if (clipToPadding) {
saveCount = canvas.save();
canvas.clipRect(mScrollX + mPaddingLeft, mScrollY + mPaddingTop,
mScrollX + mRight - mLeft - mPaddingRight,
mScrollY + mBottom - mTop - mPaddingBottom);
// We will draw our child's animation, let's reset the flag
mPrivateFlags &= ~PFLAG_DRAW_ANIMATION;
mGroupFlags &= ~FLAG_INVALIDATE_REQUIRED;
boolean more = false;
final long drawingTime = getDrawingTime();
if ((flags & FLAG_USE_CHILD_DRAWING_ORDER) == 0) {
for (int i = 0; i & i++) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
more |= drawChild(canvas, child, drawingTime);
for (int i = 0; i & i++) {
final View child = children[getChildDrawingOrder(count, i)];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
more |= drawChild(canvas, child, drawingTime);
// Draw any disappearing views that have animations
if (mDisappearingChildren != null) {
final ArrayList&View& disappearingChildren = mDisappearingC
final int disappearingCount = disappearingChildren.size() - 1;
// Go backwards -- we may delete as animations finish
for (int i = disappearingC i &= 0; i--) {
final View child = disappearingChildren.get(i);
more |= drawChild(canvas, child, drawingTime);
if (debugDraw()) {
onDebugDraw(canvas);
if (clipToPadding) {
canvas.restoreToCount(saveCount);
// mGroupFlags might have been updated by drawChild()
flags = mGroupF
if ((flags & FLAG_INVALIDATE_REQUIRED) == FLAG_INVALIDATE_REQUIRED) {
invalidate(true);
if ((flags & FLAG_ANIMATION_DONE) == 0 && (flags & FLAG_NOTIFY_ANIMATION_LISTENER) == 0 &&
mLayoutAnimationController.isDone() && !more) {
// We want to erase the drawing cache and notify the listener after the
// next frame is drawn because one extra invalidate() is caused by
// drawChild() after the animation is over
mGroupFlags |= FLAG_NOTIFY_ANIMATION_LISTENER;
final Runnable end = new Runnable() {
public void run() {
notifyAnimationListener();
post(end);
从中可以看出这个FLAG_ANIMATION_CACHE的作用了,当然还和硬件加速扯上了关系,这里先不补充相关知识,想了解的可以度娘or谷歌。
附:对硬件加速带源码分析的比较好的一篇文章:
2)View -& draw(Canvas canvas, ViewGroup parent,&long drawingTime) 方法;
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
final int flags = parent.mGroupF
if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 ||
(flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) {
caching = true;
// Auto-scaled apps are not hw-accelerated, no need to set scaling flag on DisplayList
if (mAttachInfo != null) scalingRequired =
mAttachInfo.mScalingR
caching = (layerType != LAYER_TYPE_NONE) || hardwareA
if (caching) {
if (!hardwareAccelerated) {
if (layerType != LAYER_TYPE_NONE) {
layerType = LAYER_TYPE_SOFTWARE;
buildDrawingCache(true);
cache = getDrawingCache(true);
switch (layerType) {
case LAYER_TYPE_SOFTWARE:
if (useDisplayListProperties) {
hasDisplayList = canHaveDisplayList();
buildDrawingCache(true);
cache = getDrawingCache(true);
case LAYER_TYPE_HARDWARE:
if (useDisplayListProperties) {
hasDisplayList = canHaveDisplayList();
case LAYER_TYPE_NONE:
// Delay getting the display list until animation-driven alpha values are
// set up and possibly passed on to the view
hasDisplayList = canHaveDisplayList();
从上面的代码可以分析出来,如果不禁止绘图缓存,那么每次绘制子View时都要更新缓存并且将缓存画到画布中。这无疑是多了一步,画一个bitmap,animation需要不停的画所以也就多了很多操作,但是这个缓存不是说是对绘制视图的优化嘛,这个秘密就在View的invalidate中,当子View需要 invalidate时,事实上也是交给父布局去分发的。
* This is where the invalidate() work actually happens. A full invalidate()
* causes the drawing cache to be invalidated, but this function can be called with
* invalidateCache set to false to skip that invalidation step for cases that do not
* need it (for example, a component that remains at the same dimensions with the same
* content).
* @param invalidateCache Whether the drawing cache for this view should be invalidated as
* well. This is usually true for a full invalidate, but may be set to false if the
* View's contents or dimensions have not changed.   * 指示在视图刷新时,是否也要刷新绘图缓存,对于一个完全的刷新操作,比如视图内容发生了变化,   * 或者控件尺寸发生变化了,那么应该设置true,但是如果不是二者任何一个,则应该设置为false。
void invalidate(boolean invalidateCache) {
if (skipInvalidate()) {
if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
(invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) ||
(mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED || isOpaque() != mLastIsOpaque) {
mLastIsOpaque = isOpaque();
mPrivateFlags &= ~PFLAG_DRAWN;
mPrivateFlags |= PFLAG_DIRTY;
if (invalidateCache) {
mPrivateFlags |= PFLAG_INVALIDATED;
mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
final AttachInfo ai = mAttachI
final ViewParent p = mP
//noinspection PointlessBooleanExpression,ConstantConditions
if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
if (p != null && ai != null && ai.mHardwareAccelerated) {
// fast-track for GL- just invalidate the whole hierarchy
// with a null dirty rect, which tells the ViewAncestor to redraw everything
p.invalidateChild(this, null);
if (p != null && ai != null) {
final Rect r = ai.mTmpInvalR
r.set(0, 0, mRight - mLeft, mBottom - mTop);
// Don't call invalidate -- we don't want to internally scroll
// our own bounds
p.invalidateChild(this, r);
接着,咱们再看一个ViewGroup的方法,setPersistentDrawingCache(int drawingCacheToKeep):
* Indicates what types of drawing caches should be kept in memory after
* they have been created.
* @see #getPersistentDrawingCache()
* @see #setAnimationCacheEnabled(boolean)
* @param drawingCacheToKeep one or a combination of {@link #PERSISTENT_NO_CACHE},
{@link #PERSISTENT_ANIMATION_CACHE}, {@link #PERSISTENT_SCROLLING_CACHE}
and {@link #PERSISTENT_ALL_CACHES}
public void setPersistentDrawingCache(int drawingCacheToKeep) {
mPersistentDrawingCache = drawingCacheToKeep & PERSISTENT_ALL_CACHES;
这个方法的作用,便是控制绘图缓存在被创建之后,什么时候使用。
方法的可用参数,系统提供了四个值:
1)PERSISTENT_ANIMATION_CACHE:动画前不可用,动画结束时可用,并保存此时的Cache。
2)PERSISTENT_SCROLLING_CACHE:滚动式不可用,滚动结束时可用,并保存此时的Cache。
3)PERSISTENT_ALL_CACHES:不管在什么时候,都是用缓存。
4)PERSISTENT_NO_CACHE:不适用缓存。
因此,你可以手动的控制AnimationDrawCache(在执行动画前禁用,执行完毕后启用)或者调用这个方法传入适用于相应场景的参数值就可以自动实现控制了。
大概的明白了,有木有!其实我理解的也不深入,都是在别人分析的基础上总结出来,希望对大家有用,也对自己有用。
1)2)3)4)
版权所有 爱编程 (C) Copyright 2012. . All Rights Reserved.
闽ICP备号-3
微信扫一扫关注爱编程,每天为您推送一篇经典技术文章。

我要回帖

更多关于 快速解决魔兽卡顿现象 的文章

 

随机推荐