使用CrossWork替代WebView中的一個問題

記錄一個在使用XWalkView的時候的問題;


情景再現


一個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渲染數據,

這也就合理的解釋了,爲什麼會有"只有第一次可以"和"只有第一次不可以"兩種情況了



特此記錄,







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章