23

Lightning Browserと呼ばれるオープンソースブラウザを開発していますが、Android(4.2.2)の最新のアップデートで問題が発生しました。

ビューに触れるまで、WebViewは完全にレンダリングできません。最新のAndroidバージョンでのみ発生します。4.2.1では、WebViewは完全に正常にレンダリングされました。Nexus 7を開発に使用していますが、4.2.2アップデートを受け取った直後に、ブラウザがレンダリングを停止しました。他のユーザーもこれを経験し、4.2.2でのみ発生することが何度も確認されました。APIレベル16と17をターゲットにしていますが、この問題なしにAPIレベル9をターゲットとするWebKitブラウザーを見たことがあります。

Stack Overflowで見つけた問題の解決策を使用して、これを修正しようとしました(Android WebViewは空白/白をレンダリングし、CSSの変更またはHTMLの変更でビューが更新されない、アニメーションが途切れる)。ただし、WebViewのRenderPriorityをhighに設定しただけでは解決しません...触れずにレンダリングする唯一の方法は、WebViewのOnDraw()メソッド内にinvalidate()コマンドを配置することでした。これにより、WebViewは継続的に再描画されます。これは(一種の)機能し、アニメーションはスムーズで、ページの読み込みは非常に速くなりますが、それ以外の場合はWebViewのパフォーマンスが低下します。

私もこの質問を見ました(私のものと非常に似ています)が、それに対する良い答えはありません。Android WebViewは、ユーザーとの対話までコンテンツを完全にレンダリングできません

パフォーマンスの低下とは、入力を意味します。テキスト入力が遅れ、WebView自体が以前と同様に何が起こっているかを処理できません。invalidate()メソッド呼び出しを使用してブラウザーをベンチマークすると、ベンチマークのパフォーマンスが約8%低下します。ベンチマークがすべてではないことは知っていますが、継続的な描画がシステムに負担をかけ、システムが他のタスクを無視する原因になっていることを示しています。

結論として...Android4.2.2のWebViewは、タッチされるまでレンダリングされません。これを修正するために私が知っている唯一の方法は、WebViewのonDraw()メソッドでinvalidate()を呼び出すことです。これはパフォーマンスに悪影響を及ぼします。これを修正する別の方法を探しています。

マジックコード(私は現在使用しています)...

class MyWebView extends WebView
{
    @Override
    onDraw(Canvas canvas)
    {
        invalidate(); 
        super.OnDraw(canvas);
    }
}

削除する

invalidate();

触れるまでレンダリングされません。

WebViewをどのようにレンダリングするか(私が行ったこと以外)について誰かが提案を持っていますか?ちなみに、これは私がここStackで尋ねた最初の質問です。はっきりしていない場合や、何か間違ったことをした場合は、ご容赦ください。

編集:私はここで同様の問題についてこの質問を見つけました、そしてそれは解決されました、問題は、私は答えが何を意味するのかさえ理解していません。誰かが私を啓発することができれば、それは助けになるかもしれません。

logcatでこのエラーが発生します

E/chromium(1243): external/chromium/net/disk_cache/backend_impl.cc:2022: [0705/172030:ERROR:backend_impl.cc(2022)] Corrupt Index file
4

4 に答える 4

9

そのため、最終的に WebView がレンダリングされない問題を発見しました。WebView の WebViewClient 内でドローアブルのアニメーションを開始および停止しています。このドローアブルは、ページの読み込み時に回転する単なる更新ボタンです...簡単ですよね?

ブラウザーの非フルスクリーン モードでは、回転するドローアブルと WebView は両方とも同じ親の子ですが、フルスクリーン モードでは、ドローアブルは WebView の子になります。どういうわけか、ページの読み込み中にアニメーションを開始し、完了したら (フルスクリーンで) 停止することで、アプリケーションは、回転するドローアブルがすべての描画能力を必要とし、WebView が描画されないと判断します。フルスクリーン モードでドローアブルが WebView の子になると、WebView はドローアブルよりもレンダリングの優先順位が高くなり、正常に描画されます。

話の教訓は... WebViews は、描画される最優先のビューであるのが好きです。より優先度の高いビューが他にある場合、それらは正しく描画されません。

私はアニメーションの専門家ではないので、WebView を中断しないように、drawable をアニメーション化する方法を再考する必要があります。

うまくいけば、それは理にかなっています。読んでくれてありがとう。

于 2013-03-29T17:08:36.860 に答える
2

@OlivierによるAndroid WebViewの最後の回答を参照してください私の場合、(ほとんどの) 問題はユーザーが webview に触れた後であり、それに応じていくつかの CSS を変更したため、うまくいきました。もちろん、自動/タイムアウトされたcssの場合はまったく適用されません

私の場合、Java から JavaScript 関数をエクスポートして手動で無効化を遅らせてトリガーするのにも役立ちました。そのため、JavaScript で災害が発生する可能性がある場所が多かれ少なかれわかっている場合は、WebView 内の次の内部クラスのようなもので、手動でトリガーできます。

public class MyWebView extends WebView {

    private class InvalidateExtension {

        private Handler handler=new Handler(); // you might already have a handler
        private Runnable mInvalidater=new Runnable() {

            @Override
            public void run() {
                MyWebView.this.invalidate();
            }

        }

        public void trigger(int delay) {
                handler.postDelayed(mInvalidater, delay);
                handler.postDelayed(mInvalidater, 2*delay); // just in case
                handler.postDelayed(mInvalidater, 4*delay); // just in case just in case :)
        }
    }


    /** Call this function on this view's init, BEFORE loading a page so it is available to JS */
    private void call_me_on_init_to_enable_hack() {
        addJavascriptInterface(new InvalidateExtension(), "Invalidater");
    }
}

したがって、JavaScript から次のことができます。

Invalidater.trigger(100);

そして、ミリ秒の値で遊んでください....

これが誰かを助けることを願っています!

于 2013-05-09T23:11:42.617 に答える