WebViewCompat.navigate, WebView'te web sayfası yükleme, geçmiş yönetimi ve gezinme yaşam döngüsü takibi üzerinde ayrıntılı kontrol sağlayan, WebView.loadUrl'e göre gelişmiş bir alternatiftir.
Daha önce, loadUrl kullanılarak başlatılan sayfa gezinme işlemlerinde önemli sınırlamalar vardı:
- Geçmiş girişini değiştirme yok: Geçerli geçmiş girişini değiştiremediğiniz için geri yığına giriş eklemeden yeni bir sayfaya gitmek mümkün olmuyordu.
- Ayrılmış geri aramalar:
WebViewClientiçinde belirli birloadUrlçağrısını sonraki geri arama etkinlikleriyle ilişkilendirmek için doğrudan bir mekanizma yoktu. - Ek üstbilgiler kaydedilmedi:
loadUrl'ye iletilen özel üstbilgiler,WebViewdurumu kapsamında kaydedilmediği için durum geri yüklenirken kayboldu.
WebViewCompat.navigate API, aşağıdaki özellikleri sunarak bu sorunları çözer:
- Gezinme geçmişi girişi değiştirme:
WebViewGeçmiş yığınındaki mevcut sayfayı değiştirmenize olanak tanır. - Korelasyonlu geri arama izleme: Bir gezinme yaşam döngüsünün tüm aşamalarında benzersiz tanımlayıcı olarak kullanılan bir
Navigationnesnesi döndürür. - Kaydedilmiş durum başlığı desteği: Ek başlıklar, durum geri yüklendiğinde yeniden kullanılabilmeleri için
WebViewdurum paketinde güvenilir bir şekilde kaydedilir.
Temel özellikler ve sınırlamalar
WebViewCompat.navigate'yı kullanmadan önce aşağıdaki operasyonel kuralları ve kısıtlamaları göz önünde bulundurun:
İş parçacığı güvenliği:
WebViewCompat.navigateişlevini kullanıcı arayüzü (ana) iş parçacığında çağırmanız gerekir.İptal ve öncelik: Uçuş sırasındaki navigasyonlar açıkça iptal edilemez. Ancak aynı
WebViewüzerinde yeni birnavigategörüşmesi başlatmak, etkin olan tüm navigasyonları geçersiz kılar.URI şeması desteği: Standart (ör.
https:vehttp:) ve özel URI şemaları desteklenir.javascript:şeması desteklenmiyor.URL boyutu sınırı: Desteklenen maksimum URL dizesi uzunluğu 2 MB'tır.
Özellik kontrolü: Farklı WebView APK sürümleri arasında uyumluluğu korumak için API'yi çağırmadan önce her zaman
WebViewFeature.isFeatureSupportedkullanarak özellik kullanılabilirliğini kontrol edin.
Navigasyonu başlatma ve parça yaşam döngüsünü izleme
Gezinmeyi yapılandırmak ve yaşam döngüsünü izlemek için aşağıdakileri yapın:
- Yapılandırılmış yaşam döngüsü geri aramaları almak için
WebViewkurulumu sırasındaWebViewCompat.addNavigationListenerkullanarakNavigationListeneruygulamasını kaydedin. Bellek sızıntılarını ve yinelenen geri çağırma yürütmelerini önlemek için dinleyiciyi her gezinme çağrısında değil, bir kez kaydedin. - Geçmişi değiştirme veya özel HTTP üstbilgileri gibi isteğe bağlı davranışları belirtmek için
NavigationParameters.Builderkullanarak birNavigationParametersörneği oluşturun. WebViewCompat.navigateişlevini çağırarakWebViewörneğinizi, hedef URL'yi ve parametreleri iletin.
WebViewCompat.navigate, isteği benzersiz şekilde tanımlayan bir Navigation nesnesi döndürür. Belirli bir gezinmeyi izlemek için NavigationListener geri çağırma işlemlerinizde bu nesneyi gelen Navigation parametresiyle karşılaştırın.
Uygulama örneği
Aşağıdaki örnekte gezinme parametrelerinin nasıl yapılandırılacağı, WebViewCompat.navigate işlevinin nasıl çağrılacağı ve gezinme yaşam döngüsü etkinliklerinin nasıl dinleneceği gösterilmektedir:
Kotlin
class WebNavigationManager(private val webView: WebView) {
// Track the navigation instance returned by the API
private var currentNavigation: Navigation? = null
init {
// 1. Define listener to observe navigation lifecycle events
val listener = object : NavigationListener {
override fun onNavigationStarted(navigation: Navigation) {
if (navigation == currentNavigation) {
// Navigation started
}
}
override fun onNavigationRedirected(navigation: Navigation) {
if (navigation == currentNavigation) {
// Navigation encountered a redirect
}
}
override fun onNavigationCompleted(navigation: Navigation) {
if (navigation == currentNavigation) {
if (navigation.didCommit()) {
// Navigation committed successfully
} else if (navigation.didCommitErrorPage()) {
// Navigation committed an error page
val statusCode = navigation.statusCode
val error = navigation.webResourceError
}
}
}
override fun onFirstContentfulPaintMillis(page: Page, durationMillis: Long) {
// Match page with current navigation
if (page == currentNavigation?.page) {
// Page rendering started (First Contentful Paint achieved)
}
}
}
// 2. Register listener on the main thread
WebViewCompat.addNavigationListener(webView, listener)
}
@UiThread
fun navigateToPage(url: String) {
// Check feature availability
if (!WebViewFeature.isFeatureSupported(WebViewFeature.WEBVIEW_NAVIGATE_EXPERIMENTAL_V1)) {
// Fall back to standard loadUrl if navigate API is unavailable
webView.loadUrl(url)
return
}
// 3. Configure navigation parameters
val params = NavigationParameters.Builder()
.setShouldReplaceCurrentEntry(true)
.addAdditionalHeaders(
mapOf("X-Test-Navigate-Header" to "TestValue")
)
.build()
// 4. Initiate navigation on the UI thread
currentNavigation = WebViewCompat.navigate(webView, url, params)
}
}
Java
public class WebNavigationManager {
private Navigation mCurrentNavigation;
private final WebView mWebView;
public WebNavigationManager(@NonNull WebView webView) {
mWebView = webView;
setupListener();
}
private void setupListener() {
// 1. Define listener to observe navigation lifecycle events
NavigationListener listener = new NavigationListener() {
@Override
public void onNavigationStarted(@NonNull Navigation navigation) {
if (navigation.equals(mCurrentNavigation)) {
// Navigation started
}
}
@Override
public void onNavigationRedirected(@NonNull Navigation navigation) {
if (navigation.equals(mCurrentNavigation)) {
// Navigation encountered a redirect
}
}
@Override
public void onNavigationCompleted(@NonNull Navigation navigation) {
if (navigation.equals(mCurrentNavigation)) {
if (navigation.didCommit()) {
// Navigation committed successfully
} else if (navigation.didCommitErrorPage()) {
// Navigation committed an error page
int statusCode = navigation.getStatusCode();
WebResourceErrorCompat error = navigation.getWebResourceError();
}
}
}
@Override
public void onFirstContentfulPaintMillis(@NonNull Page page, long durationMillis) {
if (mCurrentNavigation != null && page.equals(mCurrentNavigation.getPage())) {
// Page rendering started (First Contentful Paint achieved)
}
}
};
// 2. Register listener on the main thread
WebViewCompat.addNavigationListener(mWebView, listener);
}
@UiThread
public void navigateToPage(@NonNull String url) {
// Check feature availability
if (!WebViewFeature.isFeatureSupported(WebViewFeature.WEBVIEW_NAVIGATE_EXPERIMENTAL_V1)) {
// Fall back to standard loadUrl if navigate API is unavailable
mWebView.loadUrl(url);
return;
}
// 3. Configure navigation parameters
NavigationParameters params = new NavigationParameters.Builder()
.setShouldReplaceCurrentEntry(true)
.addAdditionalHeaders(Collections.singletonMap(
"X-Test-Navigate-Header", "TestValue"
))
.build();
// 4. Initiate navigation on the UI thread
mCurrentNavigation = WebViewCompat.navigate(mWebView, url, params);
}
}
Arıza modları ve hata işleme
WebViewCompat.navigate API, yapılandırma hatalarını ve çalışma zamanı gezinme hatalarını işlemek için farklı mekanizmalar sağlar:
Geçersiz bağımsız değişken istisnaları
Geçersiz bağımsız değişkenler iletildiğinde senkron bir IllegalArgumentException tetiklenir.
Bu durumun yaygın nedenleri şunlardır:
- Gerekli olan ve boş olmayan parametreler (
webView,urlveyaparams) içinnulldeğerini aktarma. javascript:gibi desteklenmeyen bir URL şeması sağlama.- RFC 2616 spesifikasyonlarına uymayan hatalı biçimlendirilmiş HTTP üst bilgisi anahtarlarının veya değerlerinin iletilmesi.
Gezinme süreci hataları
Ağ isteği veya sayfa yükleme sırasında bir hata oluşursa (ör. HTTP 404 durum kodu, DNS çözümleme hatası veya SSL hatası), WebViewCompat.navigate yine de geçerli bir Navigation nesnesi döndürür.
Gezinme işlemi tamamlandığında, hatayı teşhis etmek için Navigation
instance içinde onNavigationCompleted geri çağırma işleminizdeki aşağıdaki yöntemleri inceleyin:
getStatusCode: HTTP yanıt durum kodunu döndürür (örneğin,404veya500).getWebResourceError: Bağlantı zaman aşımları veya ana makine arama hataları gibi ağ hatalarını ayrıntılı olarak açıklayan birWebResourceErrorCompatnesnesi döndürür.didCommitErrorPage:WebView'ın hata işleyip kullanıcıya hata sayfası gösterip göstermediğini belirtir.didCommit: Gezinmenin, iptal edilmeden hedef sayfaya başarıyla uygulanıp uygulanmadığını gösterir.
Durum paketi yönetimini kaydetme
NavigationParameters ile ek başlıklar ilettiğinizde WebView, bu başlıkları kaydedilmiş durum paketine kaydeder. Böylece, durum geri yüklendiğinde bu başlıklar yeniden kullanılabilir. Ancak büyük başlık koleksiyonları, kaydedilen durumun boyutunu önemli ölçüde artırabilir Bundle.
Android durumunu kaydederken TransactionTooLargeException
olmasını önlemek için paket boyutunu sınırlamanız gerekiyorsa WebViewCompat.saveState kullanın. Bu yöntem, bayt cinsinden maksimum paket boyutu sınırı belirlemenize ve isteğe bağlı olarak ileri geçmiş öğelerini hariç tutmanıza olanak tanır:
Kotlin
// Save state with a maximum bundle size limit (for example, 64 KB)
val maxSizeBytes = 64 * 1024
val includeForwardState = false
val outState = Bundle()
WebViewCompat.saveState(webView, outState, maxSizeBytes, includeForwardState)
Java
// Save state with a maximum bundle size limit (for example, 64 KB)
int maxSizeBytes = 64 * 1024;
boolean includeForwardState = false;
Bundle outState = new Bundle();
WebViewCompat.saveState(webView, outState, maxSizeBytes, includeForwardState);
Elde edilen paket, standart WebView.restoreState yöntemiyle uyumlu olmaya devam eder.
Taşıma ve uygulama önerileri
WebView içinde gezinirken optimum performans ve kararlılık için şu önerileri uygulayın:
loadUrl'tennavigate'ye taşıma: Tüm eskiWebView.loadUrlgörüşmeleriniWebViewCompat.navigate'ye taşıyın. Bu, geçmiş yönetiminin tek tip olmasını ve başlıkların her zaman kaydedilen durumun bir parçası olarak kaydedilmesini sağlar.Özellik desteğini her zaman doğrulayın: API'yi çağırmadan önce,
WebViewFeature.isFeatureSupportedile çalışma zamanı desteğini onaylayarak eski WebView sürümlerine karşı koruma sağlayın.Gezinme örneklerini ilişkilendirme: Birden fazla
WebViewörneğini yönetirken eşzamanlı gezinmeleri ayırt etmek veya geri çağırmaları filtrelemek için döndürülenNavigationnesnesini kullanın.Başlatma sırasında işleyiciyi bir kez kaydedin:
WebViewCompat.addNavigationListener, mevcut bir işleyiciyi değiştirmek yerine işleyici eklediğinden, sonraki gezinmelerde bellek sızıntılarını ve yinelenen geri çağırma yürütmelerini önlemek içinWebViewkurulumu sırasındaNavigationListenerişleyicinizi bir kez kaydedin.Kaydetme durumu boyutunu izleme: Büyük başlık yükleri aktarırken aşırı durum verilerinin kaydedilmesini önlemek için açık boyut sınırlarıyla
WebViewCompat.saveStatekullanın.
Ek kaynaklar
Yerleştirilmiş web özellikleri ve performans optimizasyonu hakkında daha fazla bilgi edinmek için aşağıdaki kılavuzlara bakın:
- Jetpack Webkit ile WebView kullanımınızı basitleştirme
- WebView'da tahmine dayalı içerik yükleme
- WebView başlatma işlemini optimize etme
- WebView oluşturucu işleminin sonlandırılmasını işleme