1 /* 2 * Copyright 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.androidx.webkit; 18 19 import android.app.Activity; 20 import android.os.Bundle; 21 import android.text.method.ScrollingMovementMethod; 22 import android.webkit.WebView; 23 import android.webkit.WebViewClient; 24 import android.widget.LinearLayout; 25 import android.widget.TextView; 26 27 import androidx.annotation.OptIn; 28 import androidx.appcompat.app.AppCompatActivity; 29 import androidx.webkit.BlockingStartUpLocation; 30 import androidx.webkit.WebViewCompat; 31 import androidx.webkit.WebViewStartUpConfig; 32 33 import org.jspecify.annotations.Nullable; 34 35 import java.util.concurrent.Executors; 36 37 /** 38 * An {@link Activity} that calls 39 * {@link androidx.webkit.WebViewCompat#startUpWebView(WebViewStartUpConfig, WebViewCompat.WebViewStartUpCallback)} 40 * to startup WebView asynchronously and displays the summary of startup. 41 */ 42 public class AsyncStartUpActivity extends AppCompatActivity { 43 private long mStartCaptureTime; 44 45 @OptIn(markerClass = WebViewCompat.ExperimentalAsyncStartUp.class) 46 @Override onCreate(@ullable Bundle savedInstanceState)47 protected void onCreate(@Nullable Bundle savedInstanceState) { 48 // Take care not to startup WebView (including layout inflation) before the explicit call 49 // to `startUpWebView()`. 50 51 super.onCreate(savedInstanceState); 52 setContentView(R.layout.activity_async_startup); 53 setTitle(R.string.async_startup_activity_title); 54 WebkitHelpers.appendWebViewVersionToTitle(this); 55 WebViewStartUpConfig config = new WebViewStartUpConfig.Builder( 56 Executors.newSingleThreadExecutor()).build(); 57 WebViewCompat.WebViewStartUpCallback callback = result -> { 58 long duration = 59 System.currentTimeMillis() 60 - mStartCaptureTime; 61 TextView tv = findViewById(R.id.async_startup_textview); 62 tv.setMovementMethod(new ScrollingMovementMethod()); 63 tv.setText("WebView Async StartUp onSuccess() called in " + duration + " ms. \n"); 64 tv.append("getTotalTimeInUiThreadMillis: " 65 + result.getTotalTimeInUiThreadMillis() + "\n"); 66 tv.append("getMaxTimePerTaskInUiThreadMillis: " 67 + result.getMaxTimePerTaskInUiThreadMillis() + "\n"); 68 tv.append("getBlockingStartUpLocations: \n"); 69 if (result.getBlockingStartUpLocations() == null) { 70 tv.append("null \n"); 71 } else if (result.getBlockingStartUpLocations().isEmpty()) { 72 tv.append("empty list \n"); 73 } else { 74 for (BlockingStartUpLocation location : result.getBlockingStartUpLocations()) { 75 tv.append(location.getStackInformation() + "\n"); 76 } 77 } 78 // Render content in a WebView similar to real-life usage. 79 WebView wv = new WebView(this); 80 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( 81 LinearLayout.LayoutParams.MATCH_PARENT, 82 LinearLayout.LayoutParams.MATCH_PARENT 83 ); 84 LinearLayout layout = (LinearLayout) findViewById(R.id.activity_async_startup); 85 layout.addView(wv, params); 86 wv.setWebViewClient(new WebViewClient()); 87 wv.loadUrl("www.example.com"); 88 }; 89 mStartCaptureTime = System.currentTimeMillis(); 90 WebViewCompat.startUpWebView(config, callback); 91 } 92 } 93