安卓Android ViewGroup onDraw为什么没调用?

2023-10-19 09:32

本文主要是介绍安卓Android ViewGroup onDraw为什么没调用?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原帖 : link

前言

通过本篇文章,你将了解到:

1、ViewGroup onDraw不执行的原因
2、怎么让ViewGroup onDraw执行
3、setWillNotDraw(boolean)作用

如果对原理不感兴趣,请拉到最后的总结查看解决办法~

小例子

我们知道自定义view的时候会重写onDraw()方法,如下:

public class MyView extends View {
<span class="token keyword">private</span> <span class="token class-name">Paint</span> paint<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">Rect</span> rect<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">Bitmap</span> bitmap<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">Matrix</span> matrix<span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token class-name">MyView</span><span class="token punctuation">(</span><span class="token class-name">Context</span> context<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">super</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">public</span> <span class="token class-name">MyView</span><span class="token punctuation">(</span><span class="token class-name">Context</span> context<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> <span class="token class-name">AttributeSet</span> attrs<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">super</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> attrs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">public</span> <span class="token class-name">MyView</span><span class="token punctuation">(</span><span class="token class-name">Context</span> context<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> <span class="token class-name">AttributeSet</span> attrs<span class="token punctuation">,</span> <span class="token keyword">int</span> defStyleAttr<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">super</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> attrs<span class="token punctuation">,</span> defStyleAttr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>paint <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Paint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>paint<span class="token punctuation">.</span><span class="token function">setAntiAlias</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>paint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span><span class="token class-name">Color</span><span class="token punctuation">.</span>BLUE<span class="token punctuation">)</span><span class="token punctuation">;</span>rect <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rect</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">draw</span><span class="token punctuation">(</span><span class="token class-name">Canvas</span> canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">draw</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token annotation punctuation">@Override</span>
<span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">onDraw</span><span class="token punctuation">(</span><span class="token class-name">Canvas</span> canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>canvas<span class="token punctuation">.</span><span class="token function">drawRect</span><span class="token punctuation">(</span>rect<span class="token punctuation">,</span> paint<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

效果图:


image.png

蓝色的方块即是我们自定义MyView绘制的。
现在自定义一个ViewGroup:MyFrameLayout,并把MyView添加到MyFrameLayout里。

public class MyFrameLayout extends FrameLayout {
<span class="token keyword">private</span> <span class="token class-name">Paint</span> paint<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">RectF</span> rectF<span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token class-name">MyFrameLayout</span><span class="token punctuation">(</span><span class="token annotation punctuation">@NonNull</span> <span class="token class-name">Context</span> context<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">super</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">public</span> <span class="token class-name">MyFrameLayout</span><span class="token punctuation">(</span><span class="token annotation punctuation">@NonNull</span> <span class="token class-name">Context</span> context<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> <span class="token class-name">AttributeSet</span> attrs<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">super</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> attrs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">public</span> <span class="token class-name">MyFrameLayout</span><span class="token punctuation">(</span><span class="token annotation punctuation">@NonNull</span> <span class="token class-name">Context</span> context<span class="token punctuation">,</span> <span class="token annotation punctuation">@Nullable</span> <span class="token class-name">AttributeSet</span> attrs<span class="token punctuation">,</span> <span class="token keyword">int</span> defStyleAttr<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">super</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> attrs<span class="token punctuation">,</span> defStyleAttr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">addView</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MyView</span><span class="token punctuation">(</span><span class="token function">getContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>paint <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Paint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>paint<span class="token punctuation">.</span><span class="token function">setAntiAlias</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>paint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span><span class="token class-name">Color</span><span class="token punctuation">.</span>RED<span class="token punctuation">)</span><span class="token punctuation">;</span>rectF <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RectF</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token annotation punctuation">@Override</span>
<span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">dispatchDraw</span><span class="token punctuation">(</span><span class="token class-name">Canvas</span> canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">dispatchDraw</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token annotation punctuation">@Override</span>
<span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">onDraw</span><span class="token punctuation">(</span><span class="token class-name">Canvas</span> canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>canvas<span class="token punctuation">.</span><span class="token function">drawRect</span><span class="token punctuation">(</span>rectF<span class="token punctuation">,</span> paint<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

MyFrameLayout 里重写了onDraw()方法,试图绘制一个红色的矩形,并且将MyView作为子view添加到MyFrameLayout里。最后将MyFrameLayout添加到xml作为activity布局文件:

    <com.fish.myapplication.MyFrameLayoutandroid:id="@+id/myFrameLayout"android:layout_width="400dp"android:layout_height="400dp"></com.fish.myapplication.MyFrameLayout>

来看看效果:


image.png

想象中红色的矩形并没有显示出来,猜测一下原因:

1、MyView遮挡了MyFrameLayout的绘制?这个可以排除了,因为MyView蓝色区域大小:100px * 100px,而MyFrameLayout红色区域大小:200px * 200px。
2、MyFrameLayout的onDraw()没有调用。

寻根溯源

这里涉及到view的绘制流程,不进行深入阐述,大致挑重点说一下:

1、从根view(viewGroup)开始,先绘制自身,再绘制子view
2、子view继续按照第一步递归
3、如果当前view不是viewGroup,那么不会绘制子view(因为它没有孩子啊)

view绘制源码,对应上述步骤。

    public void draw(Canvas canvas) {
    <span class="token comment">//省略</span><span class="token keyword">boolean</span> horizontalEdges <span class="token operator">=</span> <span class="token punctuation">(</span>viewFlags <span class="token operator">&amp;</span> FADING_EDGE_HORIZONTAL<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">boolean</span> verticalEdges <span class="token operator">=</span> <span class="token punctuation">(</span>viewFlags <span class="token operator">&amp;</span> FADING_EDGE_VERTICAL<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>verticalEdges <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>horizontalEdges<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">// 绘制自身内容</span><span class="token function">onDraw</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 绘制子view</span><span class="token function">dispatchDraw</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//省略</span><span class="token comment">// we're done...</span><span class="token keyword">return</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">//省略</span>
<span class="token punctuation">}</span>

回到我们之前的试验,MyFrameLayout onDraw()没有执行,但是MyView onDraw()执行了,说明MyFrameLayout dispatchDraw()方法执行了,我们有理由相信MyFrameLayout draw()方法没有执行,只执行了MyFrameLayout dispatchDraw(),继续探究。

硬件加速

现在Android默认开启硬件加速,什么是硬件加速呢?为了加快Android绘制速度,适当解放cpu资源,Android将一部分绘制放到gpu执行。而对应的Android里面的canvas,也分为是否支持硬件加速,因此绘制流程也有所差异,流程图简示如下:


image.png

[]表示该调用该类里的对应方法。
()表示方法里的参数
从上图可以看出,不管是否开启硬件加速,都会经历“跳过绘制”的逻辑判断,而该判断的分支就决定了viewGroup的ondraw()方法是否执行。如果“跳过绘制”成立,那么调用dispatchDraw()方法,继而调用子view进行绘制(如果有子view)。如果“跳过绘制”不成立,那么调用draw(x1),该方法上面分析过了:会调用dispatchDraw()和ondraw()方法。

决定是否绘制的因素

从代码上分析结果来看,初步符合我们的猜想:MyFrameLayout因为某种原因,跳过了绘制,只调用了dispatchDraw()方法,从而onDraw()方法没有得到执行,最终导致没有绘制自身的内容。接下来看看“跳过绘制”的判断依据。

软件绘制:

view.java draw(x1,x2,x3)方法...// Fast path for layouts with no backgroundsif ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {mPrivateFlags &= ~PFLAG_DIRTY_MASK;dispatchDraw(canvas);} else {draw(canvas);}...

硬件加速:

view.java updateDisplayListIfDirty方法//省略// Fast path for layouts with no backgroundsif ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {dispatchDraw(canvas);drawAutofilledHighlight(canvas);if (mOverlay != null && !mOverlay.isEmpty()) {mOverlay.getOverlayView().draw(canvas);}if (debugDraw()) {debugDrawFocus(canvas);}} else {draw(canvas);}//省略

可以看出不管是否支持硬件加速,其判断依据是通过PFLAG_SKIP_DRAW标记来确定的,现在就需要找到这个标记什么时候赋值与清空的。MyFrameLayout onDraw()没执行,而MyView onDraw()执行了,那么猜测MyFrameLayout设置了 PFLAG_SKIP_DRAW标记,MyView没有设置。MyFrameLayout简单继承了FrameLayout,MyView简单继承了View,我们并没有对两者进行单独设置标记,进而猜测是viewGroup和View初始化时对于PFLAG_SKIP_DRAW标记做了不同的处理。
来看看ViewGroup初始化:


image.png

viewGroup初始化的时候,默认设置了WILL_NOT_DRAW,从字面意思来看是“不会绘制”标记,这个标记是否和PFLAG_SKIP_DRAW有联系呢?继续查看setFlags方法:

vew.java setFlags方法//省略if ((changed & DRAW_MASK) != 0) {if ((mViewFlags & WILL_NOT_DRAW) != 0) {if (mBackground != null|| mDefaultFocusHighlight != null|| (mForegroundInfo != null && mForegroundInfo.mDrawable != null)) {mPrivateFlags &= ~PFLAG_SKIP_DRAW;} else {mPrivateFlags |= PFLAG_SKIP_DRAW;}} else {mPrivateFlags &= ~PFLAG_SKIP_DRAW;}requestLayout();invalidate(true);}//省略

到此处就比较明朗,将两个标记值联系起来了:

1、如果设置了WILL_NOT_DRAW标记,那么继续检查background、foreground(mDrawable字段)、focusHighLight是否有值,如果三者任意一个设置了,那么将PFLAG_SKIP_DRAW标记清除,否则将该标记加上。
2、如果没有设置WILL_NOT_DRAW标记,那么将PFLAG_SKIP_DRAW标记清除。

至此,我们知道了MyFrameLayout onDraw()方法没有执行的原因:viewGroup默认设置了WILL_NOT_DRAW标记,进而设置了PFLAG_SKIP_DRAW标记,而在绘制的时候通过判断PFLAG_SKIP_DRAW标记来决定是否调用MyFrameLayout draw(x)方法,最终调用onDraw()方法。而view默认没有设置WILL_NOT_DRAW标记,也就没有后面的事了。

如何让viewGroup onDraw()执行

既然知道了MyFrameLayout没有绘制的原因,那么就有方法让它执行绘制流程。
先来看看WILL_NOT_DRAW

view.java/*** If this view doesn't do any drawing on its own, set this flag to* allow further optimizations. By default, this flag is not set on* View, but could be set on some View subclasses such as ViewGroup.** Typically, if you override {@link #onDraw(android.graphics.Canvas)}* you should clear this flag.** @param willNotDraw whether or not this View draw on its own*/public void setWillNotDraw(boolean willNotDraw) {setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);}
<span class="token comment">/*** Returns whether or not this View draws on its own.** @return true if this view has nothing to draw, false otherwise*/</span>
<span class="token annotation punctuation">@ViewDebug</span><span class="token punctuation">.</span><span class="token class-name">ExportedProperty</span><span class="token punctuation">(</span>category <span class="token operator">=</span> <span class="token string">"drawing"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">willNotDraw</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> <span class="token punctuation">(</span>mViewFlags <span class="token operator">&amp;</span> DRAW_MASK<span class="token punctuation">)</span> <span class="token operator">==</span> WILL_NOT_DRAW<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

View类里暴露了设置WILL_NOT_DRAW标记的接口:
setWillNotDraw(boolean willNotDraw),可以在MyFrameLayout里使用setWillNotDraw(false)。
不想设置该标记也是可行的,前面说过即使设置了WILL_NOT_DRAW,后面还是有判断background、foreground、focusHighLight是否有值。
background:view背景
foreground(mDrawable字段):view前景
focusHighLight:view获得焦点时高亮
我们只要设置了其中一个值,PFLAG_SKIP_DRAW标记将会被清空。
来看看这三个值如何影响PFLAG_SKIP_DRAW标记

view.java
public void setBackgroundDrawable(Drawable background) {
if (background != null) {if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {mPrivateFlags &= ~PFLAG_SKIP_DRAW;requestLayout = true;}}
}

public void setForeground(Drawable foreground) {
if (foreground != null) {
if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
mPrivateFlags &= ~PFLAG_SKIP_DRAW;
}
}
}

private void setDefaultFocusHighlight(Drawable highlight) {
mDefaultFocusHighlight = highlight;
mDefaultFocusHighlightSizeChanged = true;
if (highlight != null) {
if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
mPrivateFlags &= ~PFLAG_SKIP_DRAW;
}
}
}

探究了原理,我们来看看实际效果,现在给MyFrameLayout加上背景,再来看看效果:


image.png

蓝色是MyView绘制出来的
红色是MyFrameLayout绘制出来的
绿色是MyFrameLayout设置的背景
看得出来,MyFrameLayout内容已经绘制出来(红色区域)

总结

若要ViewGroup onDraw()执行,只需要setWillNotDraw(false)、设置背景、设置前景、设置焦点高亮,4个选项其中一项满足即可。

当然如果不想在MyFrameLayout onDraw里绘制,也可以重写MyFrameLayout dispatchDraw()方法,在该方法里绘制MyFrameLayout内容。

    @Overrideprotected void dispatchDraw(Canvas canvas) {canvas.drawRect(rectF, paint);super.dispatchDraw(canvas);}
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">onDraw</span><span class="token punctuation">(</span><span class="token class-name">Canvas</span> canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>

// canvas.drawRect(rectF, paint);
}

需要注意的是,super.dispatchDraw(canvas)要放到后边执行,不然子view内容会被MyFrameLayout覆盖。

更多精彩内容下载简书APP
"小礼物走一走,来简书关注我"
赞赏支持 还没有人赞赏,支持一下
fishforest
总资产27 (约1.70元) 共写了16.5W字 获得516个赞 共358个粉丝
关注

这篇关于安卓Android ViewGroup onDraw为什么没调用?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/238937

相关文章

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

Android多线程下载见解

通过for循环开启N个线程,这是多线程,但每次循环都new一个线程肯定很耗内存的。那可以改用线程池来。 就以我个人对多线程下载的理解是开启一个线程后: 1.通过HttpUrlConnection对象获取要下载文件的总长度 2.通过RandomAccessFile流对象在本地创建一个跟远程文件长度一样大小的空文件。 3.通过文件总长度/线程个数=得到每个线程大概要下载的量(线程块大小)。

时间服务器中,适用于国内的 NTP 服务器地址,可用于时间同步或 Android 加速 GPS 定位

NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备【如计算机、手机】的时间的协议。 NTP 实现什么目的?   目的很简单,就是为了提供准确时间。因为我们的手表、设备等,经常会时间跑着跑着就有误差,或快或慢的少几秒,时间长了甚至误差过分钟。 NTP 服务器列表 最常见、熟知的就是 www.pool.ntp.org/zo

高仿精仿愤怒的小鸟android版游戏源码

这是一款很完美的高仿精仿愤怒的小鸟android版游戏源码,大家可以研究一下吧、 为了报复偷走鸟蛋的肥猪们,鸟儿以自己的身体为武器,仿佛炮弹一样去攻击肥猪们的堡垒。游戏是十分卡通的2D画面,看着愤怒的红色小鸟,奋不顾身的往绿色的肥猪的堡垒砸去,那种奇妙的感觉还真是令人感到很欢乐。而游戏的配乐同样充满了欢乐的感觉,轻松的节奏,欢快的风格。 源码下载

Android SurfaceFlinger——图形内存分配器(十一)

前面的文章中的图层合成器(HWC),这里我们接着看一下 SurfaceFlinger 中的另一个重要服务——图形内存分配器。 一、简介         android.hardware.graphics.allocator@2.0 是 Android 系统中硬件抽象层(HAL)的一个组件,专门用于图形内存的分配和管理。它是 SurfaceFlinger 在处理图形数据时所依赖的

设置android返回键,保存和取得最高分

1.在.h中声明一些方法 virtual void keyBackClicked();           //Android返回键 bool isHaveSaveFile(); void getHighestHistoryScore(); 在.cpp中实现这个几个方法 void WelcomeLayer::keyBackClicked(