當前位置:首頁 » 安卓系統 » 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 14:12:00 瀏覽:648
python代碼性能 發布:2024-11-30 14:11:57 瀏覽:678
php變數是否存在 發布:2024-11-30 13:53:00 瀏覽:954
數組下標過大編譯錯誤嗎 發布:2024-11-30 13:52:51 瀏覽:639
檢測5g信號密碼是多少 發布:2024-11-30 13:52:51 瀏覽:258
c語言實現復數運算 發布:2024-11-30 13:30:17 瀏覽:768
安卓手機要怎麼下載突擊隊ol 發布:2024-11-30 13:03:42 瀏覽:637
修改密碼sql語句 發布:2024-11-30 12:54:54 瀏覽:156
搭建手游用什麼伺服器 發布:2024-11-30 12:54:09 瀏覽:171
四川密碼門鎖在哪裡買 發布:2024-11-30 12:50:29 瀏覽:401