hi Tôi đang gặp phải tình huống sau:Trình xử lý AndroidView có phản hồi gốc được nhấp vào Url trước khi tải
Tôi đang hiển thị một Trang web trải qua một WebView theo nguồn gốc phản ứng. Trên trang web này có một liên kết đến tệp PassWallet (.pkpass) (không phải là trường hợp sử dụng duy nhất). Khi tôi nhấp vào bất kỳ liên kết nào trên trang web này, tôi muốn kiểm tra xem đó là một trang web khác hoặc tệp .pkpass hay bất kỳ thứ gì. Trong khi kiểm tra này đang chạy Tôi không muốn tải bất cứ điều gì, chỉ cần chờ cho đến khi chức năng của tôi kết thúc và tôi biết nếu tôi nên mở một trang web hoặc mở một ứng dụng hoặc bất cứ điều gì. Tôi muốn làm điều này ở phía JavaScript bởi vì toàn bộ chức năng định tuyến của tôi đều ở đó và theo ý kiến phản ứng của tôi được tạo cho trường hợp này :-)
Trên iOS có chức năng đẹp này onShouldStartLoadWithRequest
.
_onShouldStartLoadWithRequest(e) {
if(checkUrl(e.url)) {
let Router = this.props.navigator.props.router;
let route = Router.getRouteFromUrl(e.url);
this.props.navigator.push(route);
return false;
}
return true;
}
Tôi nhận được sự kiện (e) và có thể kiểm tra url đang cố gắng tải. Tôi thậm chí có thể kiểm tra với e.navigationType nếu nó là một nhấp chuột hoặc bất cứ điều gì.
Hiện tại trên Android chức năng này không tồn tại. Về phía bản địa có chức năng shouldOverrideUrlLoading
nhưng chức năng này không được thực hiện trong phản ứng bản địa. Tôi tìm thấy vấn đề GitHub sau/PR https://github.com/facebook/react-native/pull/6478 Tôi đoán bây giờ, vì sự cố này đã bị đóng và do đó, có giải thích cho nên chức năng này không được triển khai.
Vì vậy, tôi bắt đầu tự tìm một cách. Tôi đã tạo ra một thành phần giao diện người dùng Native hiển thị một WebView và sau đó thực hiện phương thức này.
CustomWebViewManager.java:
package ch.mypackage;
import android.support.annotation.Nullable;
import android.webkit.WebView;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
public class CustomWebViewManager extends SimpleViewManager<CplusWebView> {
@Override
public String getName() {
return "CplusWebView";
}
@Override
protected CustomWebView createViewInstance(ThemedReactContext reactContext) {
return new CustomWebView(reactContext);
}
@ReactProp(name = "url")
public void setUrl(CustomWebView view, @Nullable String url) {
view.loadUrl(url);
}
@ReactProp(name = "javascriptEnabled")
public void setJavascriptEnabled(CustomWebView view, boolean enabled) {
view.getSettings().setJavaScriptEnabled(enabled);
}
}
CustomWebView.java
package ch.couponplus;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.events.RCTEventEmitter;
public class CustomWebView extends WebView {
EventDispatcher eventDispatcher;
EventWebClient eventWebClient;
public CustomWebView(ThemedReactContext reactContext) {
super(reactContext);
eventWebClient = new EventWebClient();
setWebViewClient(eventWebClient);
}
protected class EventWebClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
WritableMap event = Arguments.createMap();
event.putString("message", "MyMessage");
ReactContext reactContext = (ReactContext)getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
getId(),
"topChange",
event);
return true;
}
}
}
Nó hoạt động như mong đợi. Bây giờ tôi có thể kích hoạt chức năng shouldOverrideUrlLoading
trong JS và tạo nhật ký hoặc bất kỳ thứ gì.
Nhưng câu hỏi của tôi là làm cách nào để tôi có thể đặt true
hoặc false
trong Javascript để kiểm soát chức năng shouldOverrideUrlLoading
của tôi? Và có khả năng làm cho các chức năng của riêng tôi có sẵn không? Cho đến bây giờ tôi chỉ quản lý để kích hoạt sự kiện onChange
?
Tôi chỉ muốn làm giống như tôi đã tạo trong iOS :-(Có thể ai đó đến và nói với tôi rằng điều này là không thể vì bất kỳ lý do gì nhưng tôi nên làm cách nào hoặc bạn xử lý các trường hợp như thế này như thế nào? biết có những schemas Url nhưng rất nhiều tôi biết họ không làm việc trong trường hợp này.
tôi biết ơn sự giúp đỡ nào về cái này ....
nhờ cho câu trả lời của bạn. đây là một giải pháp thực sự tốt Tôi đang sử dụng điều này trong các trường hợp khác ví dụ như khi có một liên kết và tôi muốn nó mở theo quan điểm của riêng tôi chứ không phải trong webbrowser. Nhưng nếu bạn muốn mở một liên kết không được nhắm mục tiêu đến trang web như tệp .pkpass thì ứng dụng gặp sự cố vì nó bắt đầu tải liên kết trước khi bạn có thể dừng liên kết đó. Với chức năng iOS, bạn có thể dừng yêu cầu trước khi thực hiện bất kỳ hành động nào. Theo như tôi có thể kiểm tra trường hợp này 'onNavigationStateChange' được gọi sau khi một yêu cầu tải đầu tiên. Hay bạn đã tìm cách dừng tải khi bạn nhấp vào liên kết không hợp lệ? – vanBrunneren
Cách duy nhất tôi có thể nghĩ là giải quyết vấn đề này là dừng tải webview bằng cách sử dụng chức năng 'stopLoading'. Nhưng sau đó bạn nói 'onNavigationStateChage' đang được gọi sau khi yêu cầu tải .. do đó, do thời gian' stopLoading() 'được gọi - có thể đã quá muộn và ứng dụng sẽ bị lỗi. Nhưng tôi sẽ thử một lần để xem liệu giải pháp trên có hiệu quả hay không. –
Tôi không thể nói chính xác chức năng nào được gọi vào thời gian nào nhưng tôi có thể thấy rằng ứng dụng gặp sự cố trước khi tôi có thể dừng ứng dụng ngay khi tôi muốn mở một liên kết như '.pkpass' – vanBrunneren