当前位置:首页 » 安卓系统 » android刷新ui

android刷新ui

发布时间: 2023-10-15 04:55:26

Ⅰ android中如何实现UI的实时更新

1、在主线程中启动一个子线程

首先,我们需要在主线程中启动一个子线程,这个比较简单,直接在MainActivity的onCreate()方法中调用如下方法即可:

java">newThread(mRunnable).start();

2、在子线程中发送Message给Handler

在创建子线程时,我们使用了Runnable接口对象mRunnable。这里,只需要实现Runnable接口,并重写该接口的run()方法,在run()方法中实现每1秒发送一条Message给Handler即可。具体实现方法如下:

/*
*Function:实现run()方法,每1秒发送一条Message给Handler
*/
privateRunnablemRunnable=newRunnable(){
publicvoidrun(){
while(true){
try{
Thread.sleep(1000);
mHandler.sendMessage(mHandler.obtainMessage());
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
};

3、Handler接收Message通知

最后,我们创建一个Handler对象,用来接收Message通知。在收到Message通知后,完成刷新UI的操作即可。具体实现方法如下:

/*
*Function:实现handleMessage()方法,用于接收Message,刷新UI
*/
privateHandlermHandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
super.handleMessage(msg);
refreshUI();
}
};

4、刷新UI

由以上的代码可以看出,刷新UI的操作,我们是放在refreshUI()方法中来完成的。refreshUI()方法的实现也很简单,调用HttpUtils工具类中的getInputStream()方法,获得图1所示Web工程的页面内容输入流,再将该输入流转化为字符串,放入TextView控件中进行显示即可。具体实现方法如下:

/*
*Function:刷新UI
*/
privatevoidrefreshUI(){
try{
InputStreaminputStream=HttpUtils.getInputStream();
StringresultData=HttpUtils.getResultData(inputStream);
mTextView.setText(resultData);
}catch(IOExceptione){
e.printStackTrace();
}
}

Ⅱ androidUI卡顿原理分析及Vsync信号机制

一、UI卡顿定义 

1、用户角度:app操作界面刷新缓慢,响应不及时;界面滑动不够流畅; 

2、系统角度:屏幕刷新帧率不稳定,掉帧严重,无法保证每秒60帧,导致屏幕画面撕裂; 

二、UI卡顿常见原因分析以及处理方案 

1、过度绘制: 

原因:界面布局设计不合理或者过于复杂导致系统无法在16毫秒内完成渲染,view过度绘制导致CPU或者GPU负载过重,View频繁触发measure、layout操作,导致measure、layout累计耗时严重以及整个View错误的频隐让繁重新渲染; 

方案:优化界面布局,使界面布局视图扁平化,去除不必要的背景颜色,减少透明色的使用; 

方案依据原理:尽量减少View在系统中measure、layout、draw的累计时间; 

2、UI线程的复杂运算 

原因:UI主线程运算耗时 

方案:减少UI线程中数据运算,使用子线程处理耗时任务 

3、频繁GC 

原因:(1)、内存抖动;(2)、瞬间产生大量对象,消耗内存; 

方案:尽量避免在循环逻辑或者onDraw方法中频繁创建新对象和使用局部变量; 

三、android Vsync机制 

1、什么是Vsync ? 

Vsync 是Vertical Synchronization(垂直同步)的缩写,是一种在PC上很早就广泛使用的技术,可则庆以简单的把它认为是一种定时中断。而在Android 4.1(JB)中已经开始引入VSync机制,用来同步渲染,让孙携握AppUI和SurfaceFlinger可以按硬件产生的VSync节奏进行工作。 

2、Android屏幕刷新过程 

Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,屏幕的刷新过程是每一行从左到右(行刷新,水平刷新,Horizontal Scanning),从上到下(屏幕刷新,垂直刷新,Vertical Scanning)。当整个屏幕刷新完毕,即一个垂直刷新周期完成,会有短暂的空白期,此时发出 VSync 信号。所以,VSync 中的 V 指的是垂直刷新中的垂直-Vertical。 

3、没有使用Vsync的情况 

可见vsync信号没有提醒CPU/GPU工作的情况下,在第一个16ms之内,一切正常。然而在第二个16ms之内,几乎是在时间段的最后CPU才计算出了数据,交给了Graphics Driver,导致GPU也是在第二段的末尾时间才进行了绘制,整个动作延后到了第三段内。从而影响了下一个画面的绘制。这时会出现Jank(闪烁,可以理解为卡顿或者停顿)。这时候CPU和GPU可能被其他操作占用了,这就是卡顿出现的原因; 

4、使用Vsync同步 

CPU/GPU接收vsync信号,Vsync每16ms一次,那么在每次发出Vsync命令时,CPU都会进行刷新的操作。也就是在每个16ms的第一时间,CPU就会响应Vsync的命令,来进行数据刷新的动作。CPU和GPU的刷新时间,和Display的FPS是一致的。因为只有到发出Vsync命令的时候,CPU和GPU才会进行刷新或显示的动作。CPU/GPU接收vsync信号提前准备下一帧要显示的内容,所以能够及时准备好每一帧的数据,保证画面的流畅; 

5、多级缓冲 

Android除了使用Vsync机制,还使用了多级缓冲的策略来优化屏幕显示,如双重缓冲(A + B),当Display buffer A 数据时,CPU/GPU就已经在buffer B 中处理下一帧要显示的数据了。 

可是,当系统资源紧张性能降低时,导致GPU在处理某帧数据时太耗时,在Vsync信号到来时,buffer B的数据还没准备好,此时不得不显示buffer A的数据,这样导致后面CPU/GPU没有新的buffer准备数据,空白时间无事可做,后面Jank频出

因此采用三级缓冲来解决系统对性能不稳定导致的卡顿

当出现上面所述情况后,新增一个buffer C 可以减少CPU和GPU在Vsync同步间的空白间隙,此时CPU/GPU能够利用buffer C 继续工作,后面buffer A 和 buffer B 依次处理下一帧数据。这样仅是产生了一个Jank,可以忽略不计,以后的流程就顺畅了。 

注:在多数正常情况下还是使用二级缓冲机制,三级缓冲只是在需要的时候才使用;

Ⅲ Android UI线程

思考:

先必须了解下面2个问题
1.顾名思义 UI线程 就是刷新UI 所在线程
2.UI是单线程刷新

1.对Activity 来说 UI线程就是其主线程
2.对View来说 UI线程就是创建ViewRootImpl所在的线程
可以通过 WindowManager 内部会创建ViewRootImpl对象

好了,进入主题。我们来慢慢揭开面纱。
我们可以分别从几个方面切入

我们可能都有使用过 runOnUiThread 现在来看看的源码实现。

可以从上面的源码 看到
不是UI线程 就用Handler切到Handler所在的线程中,如果是UI线程直接就调用run方法。

Activity的创建:
1.Activity创建:mInstrumentation.newActivity
2.创建Context :ContextImpl (r)

我们经常用这个方法干的事情就是,要么在onCreate中获取View宽高的值。要么就是在子线程中做一些耗时操作 ,然后post切到对应View所在的线程 来绘制UI操作。那么这个对应的线程就是UI线程了。
那么这个UI线程就一定是主线程吗?
接来继续来看。它的源码View:post

mAttachInfo 在dispatchAttachedToWindow 中被赋值 ,也就是在ViewRootImpl创建的时候,所以是创建ViewRootImpl所在的线程。
attachInfo 上面时候为null 呢?在ViewRootImpl 还没来得及创建的时候,ViewRootImpl 创建是在 “onResume" 之后。所以在 Activity 的 onCreate 去View.post 那么AttachInfo 是为null 。
当 AttachInfo == null 那么会调用 getRunQueue().post(action) 。
最终这个Runnable 被 缓存到 HandlerActionQueue 中。
直到ViewRootImpl 的 performTraversals 中 调用dispatchAttachedToWindow(mAttachInfo, 0);, 那么才会去处理 RunQueue() 中的Runnable。

来张图 便于理解这个流程

我们有时候去子线程操作UI的时候(如:requestLayout),会很经常见到下面的 报错日志:
Only the original thread that created a view hierarchy can touch its views

为什么会报这个错误呢?
翻译一下:只有创建视图层次结构的原始线程才能接触到它的视图。
也就是操作UI的线程要和ViewRootImpl创建的线程是同一个线程才行,并不是只有主线程才能更新UI啊。
ViewRootImpl创建的线程?那么 ViewRootImpl 在哪里被创建的呢?

从上图可以看到ViewRootImpl创建最开始是从 ActivityThread 的HandleResumeActivity中开始 一直 ViewRootImpl 创建,也就是说ViewRootImpl 对应的UI线程和 ActivityThread 在同一个线程 也就是主线程。

好了 通过上面的讲解,上面的问题相信你可以自己回答啦~

Ⅳ Android UI刷新机制

Android屏幕的刷新包含3个步骤:CPU计算屏幕数据、GPU进一步处理和缓存、最后屏幕(Display)再从缓存中把计算的屏幕数据显示出来

对于 Android 而言,第一个步骤搜纳: CPU 计算屏幕数据 指的也就是 View 树的绘制过程,也就是 Activity 对应的视图树从根布局 DecorView 开始层层遍历每个 View,分别执行测量、布局、绘制三个操作的过程。我们重点分析的也是这个步骤,关于后续的2个步骤我们可以理解为底层处理,没必要过于深入。

我们知道Android每隔16.6ms会发送一次垂直同步VSync信息量,1S也就是60帧的画面。下面这个图蓝色的是CPU计算屏幕数据时间戳,绿色的是GPU的处理,最后黄色的是屏幕。我们可以清楚的看到,每帧的画面都会提前一帧去计算以及GPU处理。

如果我们保持页面静止,那梁橡么Android还是会16.6ms发送一次垂直同步信号量,App这个时候接受不到屏幕刷新的信号。所以也就不会让 CPU 去计算下一帧画面数据,但是底层仍然会以固定的频率来切换每一帧的画面,只是它后面切换的每一帧画面都一样,所以给我们的感觉就是屏幕没刷新

我们世渣没都知道Android的刷新离不开ViewRootImpl,在上一篇文章 《Android中UI的绘制流程》 中,大致阐述了Android的UI刷新流程。这里我们进一步深入的理解源码,以及刷新UI的详细流程。首先看图:

Ⅳ Android中Fragment怎样刷新UI

刷新UI要在主线程,Fragment和Activity是类似的,所以在要刷新UI的地方handler发送消息,在主线程中定义的hanler处理消息,更新UI,建议看下安卓的安卓handler机制。

热点内容
苹果手机锁屏怎么取消密码 发布:2024-11-30 12:28:08 浏览:860
老娘也要当间谍ftp 发布:2024-11-30 12:23:17 浏览:131
家里如何安装文件服务器 发布:2024-11-30 12:15:35 浏览:352
淘宝抢货脚本js 发布:2024-11-30 11:51:35 浏览:955
赛风怎么用安卓 发布:2024-11-30 11:42:28 浏览:982
安卓怎么充高会 发布:2024-11-30 11:29:49 浏览:657
什么是手机本地服务器ip 发布:2024-11-30 11:13:21 浏览:289
压缩袋无泵 发布:2024-11-30 11:13:11 浏览:677
去角质皮面膜怎么样配置 发布:2024-11-30 10:44:22 浏览:809
证券首次开户后为什么没密码 发布:2024-11-30 10:41:57 浏览:317