当前位置: 首页>移动开发>正文

unity手机端嵌入H5 unity支持h5

WebView篇

安卓WebView

一,安卓weiView接入如下,在安卓程序启动时调用下面方法

private void InitWebView()
{   
//动态创建一个WebView对象并添加到LinearLayout中
webView = new WebView(this);
WebSettings webSetting=webView.getSettings();
webSetting.setLoadWithOverviewMode(true);
webSetting.setJavaScriptEnabled(true); 
//此处”paraConfig”即Javascript接口名,在Javascript中通过这个接口调用Java函数。这里使用Activity作为目标对象,所以Activity类中必须有public属性的接口函数供Javascript调用。
webView.addJavascriptInterface(this, "paraConfig");
//不跳转到其他浏览器,必须要调用url拦截,不然不能请求非http和https链接
webView.setWebViewClient(new WebViewClient() 
{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{   
Log.i("Unity","shouldOverrideUrlLoading++++++++++++++++");        
//非http或者https的网络请求拦截,用action_view启动。可能报错。
try {
if (url.startsWith("http:") || url.startsWith("https:")){
return false;
}else{
Uri uri = Uri.parse(url);
Intent intent =new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
return true;          
}catch (Exception e){
Log.i("Unity","出现异常++++++++++");    
e.printStackTrace();
return false;
}                       
}
//页面加载完成
public void onPageFinished(WebView view, String url)
{
Log.i("Unity", "onPageFinished " + url);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.FILL_PARENT); 
       addContentView(webView,params); //这里可以根据具体需要,在需要的地方添加视图}
});  

//用于webView的辅助类,拦截 js 弹窗,关闭,还有进度条等等事件  
webView.setWebChromeClient(new WebChromeClient()
        { 
 
        
   
 
        
  public void onCloseWindow(WebView window) 
 
        
  {   
 
        
  Log.i("Unity", "拦截到windowClose"); 
 
        
   
 
        
     ViewGroup vg = (ViewGroup) webView.getParent();   
 
        
         vg.removeView(webView); 
 
        
         viewHierarchyId--; 
 
        
         super.onCloseWindow(window); 
 
            } 
 
        
   
 
            // 处理javascript的alert 
 
            public boolean onJsAlert(WebView view, String url, String message, final android.webkit.JsResult result) { 
 
            
  Log.i("Unity", "拦截到onJsAlert"); 
 
                return true; 
 
            }; 
 
        
   
 
        }); 
 
            
}

//在继承Activity的类下面加上以上方法即可,在需要加载界面的地方掉用一下方法

Privat void Load()

{
handler.post(new Runnable() {
@Override
public void run() {
Log.i("Unity", "------------url_webview"+url_webview);
webView.loadUrl(url_webview);
//设置Web视图  
setContentView(webView);  }
});
}

这里有个坑,如果只是单纯的 调用 webView.loadUrl( url_webview)时,会出现如下错误

A WebView method was called on thread ‘JavaBridge‘. All WebView methods must be called on the same thread。

解决的办法就是调用上面的load方法即可。

我这里用的是

public void CloseWebView(){  
Log.i("Unity","CloseWebView++Destory");
 ViewGroup vg = (ViewGroup) webView.getParent();  
 vg.removeView(webView);  
} 
*另外需要一个脚本去让js调用安卓的接口JSBridge.Java内容如下:
Public class JSBridge extends Object {
       rivate UnityPlayerActivity playerActivity;
 
       public JSBridge(UnityPlayerActivity player){  
  playerActivity=player;
  }    
  //需要添加这个@JavascriptInterface 来供js调用用来移除显示的H5界面
 @JavascriptInterface     public void CloseWebView(){  
 
 
   }  
}

*注意:由于是在游戏里面打开webView界面,最开始是用的setContentView(webView)的方式显示。会出现如下情况    Skipped rendering frame because GfxDevice is in invalid state (device lost).    最终导致程序直接崩溃,我猜可能是因为这样使安卓接管了webView视图,导致游戏视图丢失。解决方案是,在原先的基础上 使用addContentView去实现,此种需要在视图创建的时候,通过调用view.SetID去设置层级即可。js调用的JSBridge的 CoseWebView方法有个大坑。实际测试中,js调用的是可以进入到playerActivity.CloseWebView 函数里面,但是确不能移除此webView组件。具体原因还不清楚,后来通过setWebChromeClient 去重写onCloseWindow 方法 去拦截js的关闭界面,才可移除。

 

 

 

Ios篇

一 需要如下操作其中.h文件如下

#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
#import "OCJSHelper.h"
@interface WkWebViewManager : UIViewController<WKNavigationDelegate,WKUIDelegate>
@property (nonatomic, strong) UIProgressView *progressView;
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) OCJSHelper *ocjsHelper;
+(instancetype)sharedManager;
-(void)InitWKWebView;
@end

需要注意的是此文件必须继承UIViewController  和WKNavigationDelegate,WKUIDelegate这2个协议。

.m文件内容如下:

#import "WkWebViewManager.h"
@implementation WkWebViewManager
+(instancetype)sharedManager
{
static dispatch_once_t onceToken;
static WkWebViewManager *instance;
dispatch_once(&onceToken, ^{
instance = [[WkWebViewManager alloc] init];
});
return instance;
}
// 用来测试的一些url链接
- (NSURL *)testurl {
// NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];
//NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
NSURL *url = [NSURL URLWithString:@"http://dagou.daxianggames.com/pay/order_con.php?uid=10004455&appid=1001&goodsid=1&cashtype=2"];
//    NSURL *url = [NSURL URLWithString:@"https://z.yeemiao.com/share/share.html"]; // 自建证书,在iOS8下面,无法通过验证
return url;
}
-(void)InitWKWebView
{
[self clearWbCache];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.userContentController = [[WKUserContentController alloc] init];
//JS交互对象设置,kJS_Name 需要与js端保持一致
[config.userContentController addScriptMessageHandler:(id)self.ocjsHelper name:@"kJS_Namer"];
//如果是ios原生的,将UnityGetGLView()替换成self.view。我这里是基于unity上的
self.webView = [[WKWebView alloc] initWithFrame:UnityGetGLView().bounds configuration:config];
self.ocjsHelper.webView = self.webView;
//    [self.view  addSubview:webview];
self.webView.UIDelegate = self;
self.webView.navigationDelegate = self;
NSURL *url = [self testurl];
//加载页面,self.urlString是网址
NSLog(@"加载url请求++++++++++");
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
//[self.webView setHidden:true];
}
- (void)clearWbCache {
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
}
 
// 页面开始加载时调用
-(void)webView:(WKWebView*)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
NSLog(@"开始加载");
}
 
// 页面加载完成之后调用
-(void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation *)navigation{
NSLog(@"加载完成");
[UnityGetGLView() addSubview:self.webView];
}
 
// 在收到响应后,决定是否跳转
-(void)webView:(WKWebView*)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSLog(@"22222222222");
NSLog(@"%@",navigationResponse.response.URL.absoluteString);
//允许跳转
decisionHandler(WKNavigationResponsePolicyAllow);
//不允许跳转
//decisionHandler(WKNavigationResponsePolicyCancel);
}
 
// 在发送请求之前,决定是否跳转
-(void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSLog(@"%@",navigationAction.request.URL.absoluteString);
//不允许跳转
//decisionHandler(WKNavigationActionPolicyCancel);
WKNavigationActionPolicy actionPolicy = WKNavigationActionPolicyAllow;
NSString*urlString = [navigationAction.request.URL absoluteString];
urlString = [urlString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([urlString containsString:@"weixin://wap/pay?"]) 
{
actionPolicy =WKNavigationActionPolicyCancel;
//解决wkwebview weixin://无法打开微信客户端的处理
NSURL*url = [NSURL URLWithString:urlString];
if([[UIApplication sharedApplication]respondsToSelector:@selector(openURL:options:completionHandler:)]) 
{
[[UIApplication sharedApplication]openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly:@NO} completionHandler:^(BOOL success) {   }];
 
  }
else {
[[UIApplication sharedApplication]openURL:webView.URL];
}
}
//允许跳转
decisionHandler(actionPolicy);
}
 
// 加载 HTTPS 的链接,需要权限认证时调用  \  如果 HTTPS 是用的证书在信任列表中这不要此代理方法
-(void)webView:(WKWebView*)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
{
if ([challenge previousFailureCount] == 0) {
NSURLCredential *credential=[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
} else {
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
} else {
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
}
 
#pragma mark - WKUIDelegate
// 创建一个新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
NSLog(@"###############");
return [[WKWebView alloc]init];
}
 
#pragma mark - Setter & Getter
- (OCJSHelper *)ocjsHelper {
if (!_ocjsHelper) {
_ocjsHelper = [[OCJSHelper alloc] initWithDelegate:(id)self vc:self];
}
return _ocjsHelper;
}
@end
 
ocjsHelper代码如下:
.h文件代码
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
@protocol OCJSHelperDelegate <NSObject>
@optional
@end
@interface OCJSHelper : NSObject <WKScriptMessageHandler>
@property (nonatomic, weak) id<OCJSHelperDelegate> delegate;
@property (nonatomic, weak) WKWebView *webView;
 
/**
指定初始化方法
代理
实现WebView的VC
返回自身实例
 */
-(instancetype)initWithDelegate:(id<OCJSHelperDelegate>)delegate vc:(UIViewController *)vc;
@end
 
.m文件
#import "OCJSHelper.h"
@interface OCJSHelper()
@property (nonatomic, weak) UIViewController *vc;
@end
@implementation OCJSHelper
-(instancetype)initWithDelegate:(id<OCJSHelperDelegate>)delegate vc:(UIViewController *)vc; {
if (self = [super init]) {
self.delegate = delegate;
self.vc = vc;
}
return self;
}
- (void)dealloc {
NSLog(@"%@, %s", self.class, __func__);
}
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([[message.body valueForKey:@"body"] isEqualToString:@"close_win"] )    {
        [[WkWebViewManager sharedManager] colseView];
    } else {
        return;
    } 
}
@end

 

 

 


https://www.xamrdz.com/mobile/4qm1961911.html

相关文章: