반응 네이티브 WebView는 처리 방법을 반환합니다.
프로젝트의 일부 페이지 내용이 자주 변경됩니다. 이러한 페이지를 해결하려면 웹페이지를 사용하는 것이 좋습니다.
RN 프로젝트에 공개 웹 페이지를 제공하세요. 웹 콘텐츠인 경우 이 인터페이스로 이동하여 표시하세요.
현재 문제는 웹페이지에 첫 번째 수준 페이지와 두 번째 수준 페이지가 있으며 탐색 모음의 Return 키를 처리하도록 설계된다는 것입니다(Android의 Return 키 처리). .
이 문제의 해결 방법은 RN 공식 홈페이지에서 확인하실 수 있습니다. onNavigationStateChange 콜백 메소드를 사용하여 현재 탐색 상태를 기록하면 이전 페이지로 돌아갈지, 아니면 이 웹페이지를 종료하고 앱의 다른 인터페이스로 돌아갈지 결정할 수 있습니다.
그러나 웹페이지 구현이 React인 경우, 페이지가 점프할 때 onNavigationStateChange 콜백 메소드에 콜백이 없다는 것을 알게 될 것입니다! ! ! 얼마나 뚱뚱해! !
처음에는 웹 주소를 콜백을 받을 수 있는 바이두로 바꾸려고 했으나 모든게 잘 돌아가긴 했지만 우리 링크로 바꾸니 안 되서 누구 탓인가 싶어 백엔드에 전가했습니다. React를 잘못 썼습니다.
지난 프로젝트가 빡빡했고 소스 코드를 자세히 살펴볼 시간이 없었기 때문에 웹 페이지에서 js를 사용하여 앱을 다시 호출하는 완전하지 않은 솔루션을 생각해 냈습니다. 현재 탐색 상태를 알려줍니다.
이제 소스 코드를 읽고 실제 이유를 알아내는 시간을 조금 갖게 되었습니다.
이 문제의 원인과 해결 방법을 분석해 보겠습니다.
1. 먼저 소스코드의 위치를 찾습니다.
node_modulesreact-nativeReactAndroidsrcmainjavacomfacebookreactviewswebview
no de_modulesreact-nativeLibrariesComponentsWebView
디렉토리 구조는 다음과 같습니다.
2. nippet (JAVA 터미널)
RN의 실제 실행 코드는 모두 네이티브 코드입니다. 따라서 WebView 구성 요소와 같은 일부 이벤트 콜백은 실제로 네이티브 코드의 콜백에 의해 트리거됩니다. 다음과 같이
(ReactWebViewManager.java) rn 버전 0.47.1
protected static class ReactWebViewClient extends WebViewClient { //WebViewClient就是我们在写Android原生代码时,监听网页加载情况使用的工具。 protected static final String REACT_CLASS = "RCTWebView"; //定义的原生组件名,在后面JS中会对应到。 //... @Override public void onPageStarted(WebView webView, String url, Bitmap favicon) { //有很多回调方法,此处只举一例 super.onPageStarted(webView, url, favicon); mLastLoadFailed = false; dispatchEvent( webView, new TopLoadingStartEvent( //自己定义的时间,dispatch后,事件会传给js webView.getId(), createWebViewEvent(webView, url))); } //... }
(ReactWebViewManager.java) rn 버전 0.43.3 RN 버전에 따라 코드 조정이 있으므로 RN을 업그레이드할 때 신중한 회귀 테스트가 필요합니다. .
protected static class ReactWebViewClient extends WebViewClient { //WebViewClient就是我们在写Android原生代码时,监听网页加载情况使用的工具。 protected static final String REACT_CLASS = "RCTWebView"; //定义的原生组件名,在后面JS中会对应到。 //... @Override public void onPageStarted(WebView webView, String url, Bitmap favicon) { //有很多回调方法,此处只举一例 super.onPageStarted(webView, url, favicon); mLastLoadFailed = false; dispatchEvent( webView, new TopLoadingStartEvent( //自己定义的时间,dispatch后,事件会传给js webView.getId(), createWebViewEvent(webView, url))); } @Override public void doUpdateVisitedHistory(WebView webView, String url, boolean isReload) { //坑在这,这里就是导航有变化的时候会回调在这个版本是有这个处理的,但是不知道在哪个版本删掉了 -.- super.doUpdateVisitedHistory(webView, url, isReload); dispatchEvent( webView, new TopLoadingStartEvent( webView.getId(), createWebViewEvent(webView, url))); } //... }
(TopLoadingStartEvent.java) 콜백 JS 이벤트
public class TopLoadingStartEvent extends Event<TopLoadingStartEvent> { public static final String EVENT_NAME = "topLoadingStart"; //对应方法是onLoadingStart, 因为对RN的结构不熟悉,在此处花了很长时间研究是怎么对应的,最后找到了定义对应的文件 private WritableMap mEventData; public TopLoadingStartEvent(int viewId, WritableMap eventData) { super(viewId); mEventData = eventData; } @Override public String getEventName() { return EVENT_NAME; } @Override public boolean canCoalesce() { return false; } @Override public short getCoalescingKey() { // All events for a given view can be coalesced. return 0; } @Override public void dispatch(RCTEventEmitter rctEventEmitter) { rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mEventData); } }
(node_modulesreact-nativeReactAndroidsrcmainjavacomfacebookreactuimanagerUIManagerModuleConstants.java)
이 파일에는 해당 관계가 정의되어 있습니다
/** * Constants exposed to JS from {@link UIManagerModule}. */ /* package */ class UIManagerModuleConstants { /* package */ static Map getDirectEventTypeConstants() { return MapBuilder.builder() .put("topContentSizeChange", MapBuilder.of("registrationName", "onContentSizeChange")) .put("topLayout", MapBuilder.of("registrationName", "onLayout")) .put("topLoadingError", MapBuilder.of("registrationName", "onLoadingError")) .put("topLoadingFinish", MapBuilder.of("registrationName", "onLoadingFinish")) .put("topLoadingStart", MapBuilder.of("registrationName", "onLoadingStart")) .put("topSelectionChange", MapBuilder.of("registrationName", "onSelectionChange")) .put("topMessage", MapBuilder.of("registrationName", "onMessage")) .build(); } }
3. 구현된 코드 섹션 (JS 측)
(node_modulesreact-nativeLibrariesComponentsWebViewWebView.android.js)
아래 코드에서 onLoadingStart 및 onLoadingFinish만 updateNavigationState를 호출하는 것을 볼 수 있습니다. 웹 페이지 구현이 React이기 때문에 여기서 문제가 발생합니다. 단 한 페이지! 따라서 onLoadingStart 및 onLoadingFinish는 한 번만 호출됩니다. 세부정보 페이지를 다시 클릭하면 새 페이지로 이동하지 않고 원본 페이지가 새로 고쳐집니다. 따라서 updateNavigationState 콜백이 없습니다.
class WebView extends React.Component { static propTypes = { //给外部定义的可设置的属性 ...ViewPropTypes, renderError: PropTypes.func, renderLoading: PropTypes.func, onLoad: PropTypes.func, //... } render() { //绘制页面内容 //... var webView = <RCTWebView ref={RCT_WEBVIEW_REF} key="webViewKey" style={webViewStyles} source={resolveAssetSource(source)} onLoadingStart={this.onLoadingStart} onLoadingFinish={this.onLoadingFinish} onLoadingError={this.onLoadingError}/>; return ( <View style={styles.container}> {webView} {otherView} </View> ); } onLoadingStart = (event) => { var onLoadStart = this.props.onLoadStart; onLoadStart && onLoadStart(event); this.updateNavigationState(event); }; onLoadingFinish = (event) => { var {onLoad, onLoadEnd} = this.props; onLoad && onLoad(event); onLoadEnd && onLoadEnd(event); this.setState({ viewState: WebViewState.IDLE, }); this.updateNavigationState(event); }; updateNavigationState = (event) => { if (this.props.onNavigationStateChange) { this.props.onNavigationStateChange(event.nativeEvent); } }; } var RCTWebView = requireNativeComponent('RCTWebView', WebView, { //对应上面JAVA中的 ‘RCTWebView' nativeOnly: { messagingEnabled: PropTypes.bool, }, }); module.exports = WebView;
2. Solution
이제 원인을 찾았으니 해결은 쉽습니다
해결책: WebView를 맞춤화하고, doUpdateVisitedHistory 처리를 추가하고, 탐색이 바뀔 때마다 JS에 알립니다.
1. 아래 그림의 파일을 자체 프로젝트의 Android 코드 디렉터리에 복사합니다.
복사된 Android 디렉터리:
ReactWebViewManager.java에서 여러 곳을 수정해야 합니다.
public class ReactWebViewManager extends SimpleViewManager<WebView> { protected static final String REACT_CLASS = "RCTWebView1"; //此处修改一下名字 protected static class ReactWebViewClient extends WebViewClient { @Override public void doUpdateVisitedHistory(WebView webView, String url, boolean isReload) { super.doUpdateVisitedHistory(webView, url, isReload); dispatchEvent( //在导航变化的时候,dispatchEvent webView, new TopCanGoBackEvent( webView.getId(), createCanGoBackWebViewEvent(webView, url))); } } }
TopCanGoBackEvent는 탐색 변경 사항을 알리기 위해 내가 직접 추가한 이벤트입니다.
TopCanGoBackEvent.java
public class TopCanGoBackEvent extends Event<TopCanGoBackEvent> { public static final String EVENT_NAME = "topChange"; private WritableMap mEventData; public TopCanGoBackEvent(int viewId, WritableMap eventData) { super(viewId); mEventData = eventData; } @Override public String getEventName() { return EVENT_NAME; } @Override public boolean canCoalesce() { return false; } @Override public short getCoalescingKey() { // All events for a given view can be coalesced. return 0; } @Override public void dispatch(RCTEventEmitter rctEventEmitter) { rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mEventData); } }
Create a new ReactWebViewPage.java
public class ReactWebViewPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Arrays.<ViewManager>asList( new ReactWebViewManager() ); } }
그런 다음 MainApplication
에 이 모듈을 추가하세요.
public class MainApplication extends Application implements ReactApplication { @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new ReactWebViewPackage() //WebView ); } }
The 위의 내용은 Android에서 수정해야 할 사항입니다. iOS에서는 시도해 본 적이 없습니다.
2. 아래 그림의 파일을 자체 프로젝트의 JS 코드 디렉터리에 복사하고 이름을
JS 코드 디렉터리로 변경합니다.
CustomWebView.android.js 필요한 곳이 여러 군데 있습니다. 수정됩니다.
/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule CustomWebView //此处需要修改名称 */ var RCT_WEBVIEW_REF = 'webview1'; //此处需要修改名称 render() { var webView = <NativeWebView onLoadingStart={this.onLoadingStart} onLoadingFinish={this.onLoadingFinish} onLoadingError={this.onLoadingError} onChange={this.onChange} //添加方法 />; return ( <View style={styles.container}> {webView} {otherView} </View> ); } onChange = (event) => { //添加方法 this.updateNavigationState(event); }; } var RCTWebView = requireNativeComponent('RCTWebView1', CustomWebView, CustomWebView.extraNativeComponentConfig); //修改名称 module.exports = CustomWebView; //修改名称
至此就完成自定义WebView模块。也可以解决网页是React实现,不能导航的问题。
위 내용은 반응 네이티브 WebView는 처리 방법을 반환합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











1. 모듈을 사용하여 파일에 로그 출력: 로깅은 사용자 정의 수준 로그를 생성하고 지정된 경로에 로그를 출력할 수 있습니다. 로그 수준: 디버그(디버그 로그) = 5) {clearTimeout(시간) // 한 번에 모두 10번 획득한 경우 행이 비어 있음 로그 지우기 예약 작업}return}if(data.log_type==2){//(i=0;i에 대해 새 로그를 얻은 경우)

Java13의 새로운 JavaFXWebView 구성 요소를 사용하여 웹 컨텐츠를 표시하십시오. Java의 지속적인 개발로 인해 JavaFX는 크로스 플랫폼 그래픽 인터페이스를 구축하기 위한 주요 도구 중 하나가 되었습니다. JavaFX는 풍부한 그래픽 라이브러리와 구성 요소를 제공하므로 개발자는 다양한 사용자 인터페이스를 쉽게 만들 수 있습니다. 그중 JavaFXWebView 구성 요소는 JavaFX 응용 프로그램에서 웹 콘텐츠를 표시할 수 있는 매우 유용한 구성 요소입니다. Java13에서는 J

Caddy 소개 Caddy는 현재 Github에 38,000개 이상의 별이 있는 강력하고 확장성이 뛰어난 웹 서버입니다. Caddy는 Go 언어로 작성되었으며 정적 리소스 호스팅 및 역방향 프록시에 사용할 수 있습니다. Caddy에는 다음과 같은 주요 기능이 있습니다. Nginx의 복잡한 구성에 비해 원래 Caddyfile 구성은 매우 간단합니다. 기본적으로 자동화된 HTTPS 구성을 지원하고 HTTPS 인증서를 자동으로 적용할 수 있습니다. 수만 개의 사이트를 Go 언어로 작성하여 어디서나 실행할 수 있으며 메모리 안전성이 더욱 보장됩니다. 우선 CentO에 직접 설치해보겠습니다.

양식 유효성 검사는 웹 애플리케이션 개발에서 매우 중요한 링크로, 애플리케이션의 보안 취약성과 데이터 오류를 방지하기 위해 양식 데이터를 제출하기 전에 데이터의 유효성을 확인할 수 있습니다. Golang을 사용하여 웹 애플리케이션에 대한 양식 유효성 검사를 쉽게 구현할 수 있습니다. 이 기사에서는 Golang을 사용하여 웹 애플리케이션에 대한 양식 유효성 검사를 구현하는 방법을 소개합니다. 1. 폼 유효성 검사의 기본 요소 폼 유효성 검사를 구현하는 방법을 소개하기 전에 먼저 폼 유효성 검사의 기본 요소가 무엇인지 알아야 합니다. 양식 요소: 양식 요소는

JavaAPI 개발에서 웹 서버 처리를 위해 Jetty7 사용 인터넷의 발전과 함께 웹 서버는 애플리케이션 개발의 핵심 부분이 되었으며 많은 기업의 초점이기도 합니다. 증가하는 비즈니스 요구를 충족하기 위해 많은 개발자가 웹 서버 개발에 Jetty를 사용하기로 선택했으며 그 유연성과 확장성은 널리 인정받고 있습니다. 이 기사에서는 We 용 JavaAPI 개발에서 Jetty7을 사용하는 방법을 소개합니다.

얼굴 차단 사격은 영상 속 인물을 가리지 않고 다수의 사격이 떠다니는 것처럼 보이도록 하여 마치 인물 뒤에서 떠다니는 것처럼 보이게 하는 것을 의미합니다. 기계 학습은 몇 년 동안 널리 사용되었지만 많은 사람들은 이러한 기능을 브라우저에서도 실행할 수 있다는 사실을 모릅니다. 이 기사에서는 기사 마지막 부분에 적용 가능한 몇 가지 시나리오를 소개합니다. 이 솔루션을 통해 몇 가지 아이디어를 얻을 수 있기를 바랍니다. mediapipeDemo(https://google.github.io/mediapipe/)는 주류 얼굴 차단 공세 주문형 업로드의 구현 원리를 보여줍니다. 비디오 서버 백그라운드 계산은 비디오 화면의 세로 영역을 추출하고 이를 svg로 변환합니다. 클라이언트가 비디오를 재생하는 동안 서버에서 svg를 다운로드하고 사격, 초상화와 결합합니다.

웹 표준은 W3C 및 기타 관련 기관에서 개발한 일련의 사양 및 지침으로, HTML, CSS, JavaScript, DOM, 웹 접근성 및 성능 최적화를 포함하며, 이러한 표준을 따르면 페이지의 호환성이 향상됩니다. 접근성, 유지 관리성 및 성능. 웹 표준의 목표는 웹 콘텐츠가 다양한 플랫폼, 브라우저 및 장치에서 일관되게 표시되고 상호 작용할 수 있도록 하여 더 나은 사용자 경험과 개발 효율성을 제공하는 것입니다.

우선, frp가 무엇인지에 대해 의문이 생길 것입니다. 간단히 말해서, frp는 인트라넷 침투 도구입니다. 클라이언트를 구성한 후 서버를 통해 인트라넷에 액세스할 수 있습니다. 이제 내 서버는 nginx를 웹 사이트로 사용했으며 포트 80은 하나만 있습니다. FRP 서버도 포트 80을 사용하려면 어떻게 해야 합니까? 쿼리 후에는 nginx의 역방향 프록시를 사용하여 이를 수행할 수 있습니다. 추가하려면: frps는 서버이고 frpc는 클라이언트입니다. 1단계: 서버에서 nginx.conf 구성 파일을 수정하고 nginx.conf의 http{}에 다음 매개변수를 추가합니다. server{listen80
