情景再現
一個HTML頁面中有個輸入框,在點擊這輸入框,彈出軟鍵盤時,軟鍵盤會遮蓋到輸入框.
經百度一番,這個問題可以用AndroidBug5497Workaround這個工具類解決
經過一段時間的使用,發現如果Theme中設置了<item name="android:windowIsTranslucent">true</item>,
則鍵盤下落時會顯示上一層頁面,一閃而過,在性能較差的機器上尤爲明顯,經放慢截圖是這樣:
如果Theme中設置了<item name="android:windowIsTranslucent">false</item>,
則鍵盤下落時會顯示黑色,一閃而過,在性能較差的機器上尤爲明顯
經過一番折騰,發現只要XWalkView改變Size,就會出現黑屏或者透明的問題.點進去,看了一下XWalkView的代碼,
發現在創建XWalkView對象的時候,創建了一個SurfaceView對象,會不會是SurfaceView的鍋呢?
百度了一下SurfaceView的遮蓋,背景之類的問題,發現給XWalkView在onXWalkReady()方法中設置
walkView.setZOrderOnTop(true)會解決黑屏
walkView.setZOrderOnTop(true)這行代碼就是設置內部SurfaceView對象的,使之顯示在SurfaceView所在window窗體的最上
面
心裏是樂開了花啊,感覺全世界都是渣渣,我特麼最牛逼
但是好景不長,walkView.setZOrderOnTop(true)代碼之後,只有第一次進入頁面可以顯示數據,從第二次開始就再也無法顯示數據
了
重新打開其他的頁面,還是可以顯示的...內心一萬隻草泥馬在奔騰...
從此疑惑一段時間,最終決定把walkView.setZOrderOnTop(true)這行代碼下掉
一段時間後,迫於老總壓力,重新研究這個bug.
經google,(https://crosswalk-project.org/jira/browse/XWALK-6628)發現可以用
1), Apply XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true); before new XWalkView
2), mXWalkView.setBackgroundColor(Color.TRANSPARENT);
這兩行代碼解決下落時的黑色,果斷嘗試了一下.第一次在4.4的機器上成功了,也是舒了一口氣,終於解決了這個問題嗎?都不敢相信了,所以換了個高檔手機試了一下
並沒有什麼卵用,XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true)這行代碼在Android7.0
以上會拋運行時異常:
TextureView doesn't support displaying a background drawable,直接閃退,絕不猶豫查了XWalkView的源碼,果然在ANIMATABLE_XWALK_VIEW爲true時,會用TextureView來渲染數據,在
ANIMATABLE_XWALK_VIEW爲false時,
用SurfaceView來渲染 所以這種方法GG
又看到SurfaceView,我趕緊百度了下,SurfaceView到底是個什麼神奇的東西,說什麼獨立的window,什麼什麼的,可是獨立的
window,爲啥我讓他顯示在最上面了,還是出問題呢?而且第一次好像是成功了啊,之後在進入爲啥就黑屏了呢?很納悶...
想了一會兒,是不是有其他的SurfaceView覆蓋在上面了呢?但是XWalkView中只有實例化的時候創建了一個SurfaceView啊
決定遍歷一下XWalkView的視圖樹,發現SurfaceView就給設置setZOrderOnTop(true),
private void setZOrderOnTopFlag(ViewGroup viewGroup, boolean flag) {int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = viewGroup.getChildAt(i);
if (child instanceof SurfaceView) {
((SurfaceView) (child)).setZOrderOnTop(flag);
LogUtils.tag("設置setZOrderOnTop").e(viewGroup.getClass().getName() + "中" + child.toString());
return;
}
if (child instanceof ViewGroup) {
setZOrderOnTopFlag((ViewGroup) child, flag);
}
}
}
經過這個代碼一跑,我擦,第一次進入都不顯示數據了....涼涼
又點了一次,臥槽,竟然第二次可以,再點,第三次也可以,再點.....
發現了規律,只有第一次顯示不了...
我敲裏嗎,這都行?一開始只有第一次可以,現在只有第一次不可以...神bug,牛逼!!!
既然如此,就不要怪我心狠手辣了...
於是乎,我在onXWalkReady()方法中寫了walkView.setZOrderOnTop(true)
跑一下,完美~~~
可是,爲什麼呢?
打log,觀察到,除了XWalkView中有SurfaceView,在XWalkView內部中的XWalkContent這個對象也有一個SurfaceView對象,
當時就覺得...哇~~~果然如我只所料,不是一個SurfaceView在鬧騰啊
多次運行,打log發現,首次進入的時候,用XWalkView中的SurfaceView渲染數據,之後用XWalkContent中的SurfaceView渲染數據,
這也就合理的解釋了,爲什麼會有"只有第一次可以"和"只有第一次不可以"兩種情況了