1. 程式人生 > >iOS WebView中的JS互動

iOS WebView中的JS互動

前言:

一段時間了,手頭的工作照常進行中,之前有好幾個主題一直想寫,但又擱置了,主要是主題有點大,看樣子路還是要一步一步走的;

前幾天,收到了一份面試通知,一家比較大的網際網路企業吧,想想自己也沒什麼面試經驗,總想著要換個環境,也想換個角度審視一下自己,所以就去了,真心是沒準備什麼,臨行前把幾個常用演算法翻出來看了看……這裡就說說我的體會吧(可能會佔一定篇幅,誰讓這是我的地盤呢)

到了之後,人力的同學帶我上樓,先是筆試1h,之後是面試,大概又是1h吧;筆試的內容,基礎的比如:weak、assign等關鍵字的使用場景,KVO的實現機制等,const/static的用法,CALayer層的使用,響應者鏈的概念,多執行緒GCD、NSOperation手寫程式碼示例,手寫單例和遞迴函式;還有一些內容比較新,因為有幾個內容是最近一些主頁論壇分享出來的文章,或是一直以來討論的主題,比如:如何高效的切割圓角,app的效能優化等;

大概答了一些,覺得自己說不明白的也就沒寫,面試官來了,就開始聊我回答的問題,涉及到的其實主要還是記憶體管理,多執行緒的使用,資料結構的常見問題,比如連結串列,二叉樹遍歷,快排演算法等一些基礎的演算法思想……最後也問道了app框架上,設計模式等等;

其實很多東西都能說一點,但是瞭解的又不夠深入,總的來說,這是一次失敗的面試,但同時也是一次寶貴的經驗,面試技巧上就不提了,因為我做的也不好,哪能一兩次面試就總結出一堆真知灼見來,不過這次面試的內容,還是引起了我的思考:從開始接觸iOS開發,到今天差不多2年半了,時間並不短,對開發的理解也在逐漸變化,以前覺得實現需求順利就可以了,忽視了軟體開發其實是一個比較完成的體系,簡單的實現可能只是冰山一角,深入的瞭解底層的原理,真的非常重要,新的知識也要及時接觸和實踐,在這些方面我做的還明顯不夠,好了,說了一堆廢話,算是與君共勉,接下來我們來看這次的主題;

UIWebView和WKWebView:

iOS8之前,對於webview的展示,我們使用UIWebView,在iOS8之後,蘋果推出了WKWebView,webkit使用WKWebView來代替UIWebView和OS X的WebView,新提供的WKWebView執行JS可以和Safari一樣快,記憶體上也優化了很多,這個大家在使用時可以很明顯的看出來,我就不舉例了;

UIWebView使用NSURLCache快取,通過setSharedURLCache可以設定成我們自己的快取,但WKWebview並不支援NSURLCache,相關快取的清除我一會會給出;

對於簡單的webview載入,其實兩個控制元件用起來大同小異,都有各自的協議回撥相應的頁面載入過程,由於在新專案中已經不再支援iOS8以前的系統了,所以自然就想到了用WKWebView;

需求上需要進行JS的互動,這也就是我本次要討論的主題,讓我們先來熟悉一下WKWebView;

WKWebView API:

在使用之前需要先匯入framework:

接下來可以看下WKWebView的API:(我只列舉一部分)

@property (nonatomic, readonly, copy) WKWebViewConfiguration *configuration;
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
@property (nonatomic, readonly) double estimatedProgress;
@property (nonatomic, readonly) BOOL canGoBack;
@property (nonatomic, readonly) BOOL canGoForward;
- (nullable WKNavigation *)goBack;

- (nullable WKNavigation *)goForward;

- (nullable WKNavigation *)reload;
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
這幾個包括了:

WKWebView初始化時的配置屬性;初始化方法;載入url的方法;當前的載入狀態;載入進度;前進/後退操作;解釋執行JS語句的方法;

意思都比較清晰,熟悉就好;

WKWebView的使用:

使用之前先匯入標頭檔案:

#import <WebKit/WebKit.h>
接下來讓我們看一段初始化的程式碼:
 WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    
    // 設定偏好設定
    config.preferences = [[WKPreferences alloc] init];
    // 預設為0
    config.preferences.minimumFontSize = 10;
    // 預設認為YES
    config.preferences.javaScriptEnabled = YES;
    // 在iOS上預設為NO,表示不能自動通過視窗開啟
    config.preferences.javaScriptCanOpenWindowsAutomatically = YES;
    
    // web內容處理池
    config.processPool = [[WKProcessPool alloc] init];
    
    // 通過JS與webview內容互動
    config.userContentController = [[WKUserContentController alloc] init];
    // 注入JS物件名稱createdoctor,當JS通過createdoctor來呼叫時,
     [config.userContentController addScriptMessageHandler:self name:@"createdoctor"];
    
    self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0,ScreenWidth , ScreenHeight - 64) configuration:config];
    
    // 新增KVO監聽
    [self.webView addObserver:self
                  forKeyPath:@"loading"
                     options:NSKeyValueObservingOptionNew
                     context:nil];
    [self.webView addObserver:self
                  forKeyPath:@"title"
                     options:NSKeyValueObservingOptionNew
                     context:nil];
    [self.webView addObserver:self
                  forKeyPath:@"estimatedProgress"
                     options:NSKeyValueObservingOptionNew
                     context:nil];
    
    self.webView.UIDelegate = self;
    self.webView.navigationDelegate = self;
    
    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
    
    [self.view addSubview:self.webView];

這其中有兩個類值得我們特別關注下:WKWebViewConfiguration和WKUserContentController;

我們注意到WKWebViewConfiguration對應的物件在設定相關屬性之後,作為WKWebView初始化的配置項傳入;WKUserContentController的例項作為註冊JS物件的容器存在(有新增就有移除,api裡方法都有);這兩個類的API我就不列在這了,沒幾個方法,大家看下就行;

這段程式碼可以分為四個部分:

1.配置例項config的初始化,注意頁面的一些設定都是在preferences的屬性中設定的,config例項還有一個比較重要的屬性是websiteDataStore(WKWebsiteDataStore),儲存的資訊類似UIWebView的快取資訊,這個類會在清理快取的時候用到;

2.WKUserContentController例項註冊JS物件;

3.WKWebView初始化及URL載入;

4.KVO監聽載入狀態,頁面標題,載入進度 幾個屬性的變化;

1、3、4相信大家都比較清楚,主要是第2步,那接下來我就做下說明:

app webview呼叫執行JS,很簡單,使用WKWebView,只需要用相應的例項呼叫方法即可:

    NSString * js = @"alert('Objective-C call js to show alert');window.webkit.messageHandlers.createdoctor.postMessage('要告訴app醫生已經建立成功 你可以進行介面切換了')";
    [self.webView evaluateJavaScript:js completionHandler:nil];

就像這樣;

也可以提前注入一個js方法,在需要呼叫的時候執行相應方法即可,這樣就不用每次都寫一段js程式碼來解釋執行了:

    //js注入,注入一個測試方法。
    NSString *javaScriptSource = @"function userFunc(){window.webkit.messageHandlers.createdoctor.postMessage( {\"name\":\"HS\"})}";
    WKUserScript *userScript = [[WKUserScript alloc] initWithSource:javaScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];// forMainFrameOnly:NO(全域性視窗),yes(只限主視窗)
    [config.userContentController addUserScript:userScript];


但是實際的應用場景要稍複雜些,比如說前後端的傳值(這裡我先把app這裡叫前端,JS端成為後端,這是相對來講的,大家理解就行):

1.如果前端希望後端處理一些場景,但是還需要提供一下前端才有的資料,這是就需要在前端呼叫執行後端在頁面中提供的js方法,進行傳值,即“前->後”;

2.相應的,在後端處理了一些事物之後,或是需要主動觸發前端的相關操作,就需要把具體的結果通過前端註冊的JS物件,並呼叫方法,進行傳值,即“後->前”;

前面提到的註冊js物件,對應的就是“後-前”的這種場景,我們可以看下這個方法:

     [config.userContentController addScriptMessageHandler:self name:@"createdoctor"];
Handler:是遵循WKScriptMessageHandler協議的例項物件,通過該協議的回撥方法,回去服務端傳過來的引數:
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
        NSLog(@"\nJS:\nname-%@;\nbody-%@\n",message.name,message.body);

}
這裡指定為當前的檢視控制器;

name:指定的值是一個字串,這個字串,或被webkit解釋成一個物件,供後端使用,使用的格式形如:

window.webkit.messageHandlers.createdoctor.postMessage('哈哈哈')"

其中createdoctor就是我們註冊時傳入的name,可以註冊多個JS物件(注意有註冊就要有移除)供後端在不同的業務場景中呼叫,postMessage是一個方法,裡邊傳的是引數;

若使用上邊的程式碼那我們在離開這個ViewController的時候,在dealloc中就需要做幾件事情:

一直提到要移除已經註冊的JS物件,所以這裡要呼叫WKUserContentController的例項方法

[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"createdoctor"];
同時還要移除KVO的監聽;

還有一個(如果在意的話),就是清除快取:
之前提到的WKWebsiteDataStore類是iOS9之後提供的,我們可以用它來清除webview儲存的資料;

                NSSet *websiteDataTypes = [NSSet setWithArray:@[
                                                                WKWebsiteDataTypeDiskCache,
                                                                WKWebsiteDataTypeOfflineWebApplicationCache,
                                                                WKWebsiteDataTypeMemoryCache,
                                                                WKWebsiteDataTypeLocalStorage,
                                                                WKWebsiteDataTypeCookies,
                                                                WKWebsiteDataTypeSessionStorage,
                                                                WKWebsiteDataTypeIndexedDBDatabases,
                                                                WKWebsiteDataTypeWebSQLDatabases
                                                                ]];
有很多型別是吧,區分不出來,就全刪掉好了:
        NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
        NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
        [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes
                                                   modifiedSince:dateFrom completionHandler:^{
                                                       // code
                                                   }];
但是還會有這樣的疑問,既然這個類是iOS9之後才有的,那iOS8中WKWebView的快取如何清理啊,我在網上找了一段程式碼:
        //wkwebview快取清空
        NSString *libraryDir = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
                                                                   NSUserDomainMask, YES)[0];
        NSString *bundleId  =  [[[NSBundle mainBundle] infoDictionary]
                                objectForKey:@"CFBundleIdentifier"];
        NSString *webkitFolderInLib = [NSString stringWithFormat:@"%@/WebKit",libraryDir];
        NSString *webKitFolderInCaches = [NSString
                                          stringWithFormat:@"%@/Caches/%@/WebKit",libraryDir,bundleId];
        NSString *webKitFolderInCachesfs = [NSString
                                            stringWithFormat:@"%@/Caches/%@/fsCachedData",libraryDir,bundleId];
        
        NSError *error;
        [[NSFileManager defaultManager] removeItemAtPath:webKitFolderInCaches error:&error];
        [[NSFileManager defaultManager] removeItemAtPath:webkitFolderInLib error:&error];
        [[NSFileManager defaultManager] removeItemAtPath:webKitFolderInCachesfs error:&error];
這個我也沒試過好不好用(一會再和大家講為什麼沒試),實質就是去本地找快取路徑,然後清空指定路徑的資料;

有了這些準備之後,接下來我們來實踐一下,這裡需要藉助Safari提供的Web檢查器進行JS的除錯;

使用Safari進行web除錯:

先看下如何使用Safari進行除錯,大家看看這幾張圖就知道了:

現在我用手機開啟一個我專案中的url,就可以通過Safari進行除錯了:

在出現的網頁檢查器中刻意直接輸入JS的程式碼,執行相關方法進行測試,比如我執行一個alert()方法:

傳入引數1的話,在我app中相應的webView上就會顯示一個alert彈窗提示“1”;

注意:WKWebView對於這類alert有單獨的代理方法進行處理,如:

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
需要在這個方法中,實現UIAlertController否則該彈窗不會顯示;

app端-JS端:

app端給js端傳值,只需呼叫evaluateJavaScript方法執行JS提供的方法即可;

當前webview中js提供了一個方法,如fnCommon,他有兩個引數(我們傳的是公參和私有引數,你用的話可以隨便傳點什麼,這些方法實現時商定即可)

在控制檯也是可以呼叫到這個方法的:

實際呼叫的話可以這樣:

    NSString * js = [NSString stringWithFormat:@"fnCommon(\'%@\',\'%@\')",pubStr,priStr];
    [self.webView evaluateJavaScript:js completionHandler:nil];
JS端拿到傳遞的引數,處理即可;

JS端-app端:

這個場景前面我們已經論述過了,這裡直接給出控制檯執行的示例:

執行這句程式碼之後,app中的webview就會呼叫WKScriptMessageHandler協議的代理方法:

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
        NSLog(@"\nJS:\nname-%@;\nbody-%@\n",message.name,message.body);

}
name就是createdoctor;

body就是postMessage傳入的字串引數;

這裡給出客戶端的log,大家可以試一下;


無法釋放的問題:

前面我們已經講過,在js端呼叫app端時需要註冊JS物件:

    [config.userContentController addScriptMessageHandler:self name:@"createdoctor"];
我們將代理設定為self,註冊了對用的就是移除,我們是在dealloc中做的,但是實際除錯過程中,我們發現退出介面後,dealloc方法並沒有執行,這裡貌似是self物件被強引用得不到釋放造成的,這裡我們可以通過自定義一個實現WKScriptMessageHandler協議的物件,如HQScriptMessageHandler:
    HQScriptMessageHandler * messageHandle = [[HQScriptMessageHandler alloc]initWithDelegate:self];
    [config.userContentController addScriptMessageHandler:messageHandle name:@"createdoctor"];
在這個類中實現相應的回撥方法,並處理即可,這樣self就能正常釋放,dealloc方法就會被呼叫了;

物件釋放的問題:

在執行“window.webkit.messageHandlers.createdoctor.postMessage('要告訴app醫生已經建立成功 你可以進行介面切換了') ”這句程式碼之後,雖然在WKScriptMessageHandler協議的代理方法中收到了正常的JS端傳過來的引數,但是出現了crush:在被釋放的物件並沒有被初始化……


………………這個malloc_error_break咋debug啊?(我只想說,我的內心是崩潰的>_<,這就是前面iOS8下清快取的方式我沒試的原因)

沒辦法的辦法:

這個bug除錯了一段時間,找了幾個同業的牛人請教了一下,奈何人家寫的code就沒問題;在論壇上提了還沒回復;最終我的解決方案是暫時使用UIWebView實現JS的互動,優先實現功能,這也是沒辦法的辦法;

限於個人能力,沒能將這個問題解決掉,希望有遇到相同情況的同學在看到我的文章之後,能指點一二,萬分謝謝;

我自己也會繼續嘗試解決這個問題,有了進展我會更新上來,方便大家交流;

UIWebView API:

得,又回來看我們的老朋友了:

@property (nullable, nonatomic, assign) id <UIWebViewDelegate> delegate;

- (void)loadRequest:(NSURLRequest *)request;

- (void)reload;
- (void)stopLoading;

- (void)goBack;
- (void)goForward;

@property (nonatomic, readonly, getter=canGoBack) BOOL canGoBack;
@property (nonatomic, readonly, getter=canGoForward) BOOL canGoForward;
@property (nonatomic, readonly, getter=isLoading) BOOL loading;


在初始化webView檢視之後,我們可以通過loadrequest方法載入相應的介面
NSString * url = @"http://www.baidu.com";
    NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    self.webView.delegate = self;
    [self.webView loadRequest:request];

load、reload、stoploading這個幾個方法對應屬性loading的狀態值;

goback方法使用時需要判斷屬性canGoBack的值;goForward方式使用時需要判斷屬性canGoForward的值;這兩個方法是處理webview內連線介面切換的;(對於跨域的連結需要手動開啟)

看起來是不是和WKWebView差不多;

執行js程式碼使用如下方法:

- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

其他屬性就不看了,協議的代理方法又一個還是需要注意下:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
通過這個代理方法,也是可以實現原生和js互動的,在這個方法裡面。可以拿到每一個URL,通過對URL的引數欄位監測分析,可以實現JS呼叫OC程式碼;

用一個比較形象的詞就是”url重定向“(姑且這樣講吧)

我們要用這種方式嗎?當然不是,iOS7之後,蘋果提供了一個新的庫JavaScriptCore(對應標頭檔案#import <JavaScriptCore/JavaScriptCore.h>),用來做JS互動,我們就用這個;

JavaScriptCore:

JavaScriptCore是webkit的一個重要組成部分,主要是對JS進行解析和提供執行環境。使用起來也比較簡單,深入瞭解的話推薦大家看看這篇文章

這裡,我就直接放程式碼了,用起來都差不多;

app端=>JS端:

    NSString * pubStr = [pubPara toJSONString];
    NSString * priStr = [priPara toJSONString];
    
    NSString * js = [NSString stringWithFormat:@"fnCommon(\'%@\',\'%@\')",pubStr,priStr];
    [self.webView stringByEvaluatingJavaScriptFromString:js];

呼叫webview方法,直接解釋執行js程式碼即可;

或是參考上邊文章中的這種方式

   self.context = [[JSContext alloc] init];

    NSString *js = @"function add(a,b) {return a+b}";

    [self.context evaluateScript:js];

    JSValue *n = [self.context[@"add"] callWithArguments:@[@2, @3]];

    NSLog(@"---%@", @([n toInt32]));//---5
這種其實和WKWebView的js注入有點像;

JS端=>app端:

首先定義一個物件,並宣告一個繼承自JSExport協議的協議:

.h

#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>

@protocol HQJSProtocal <JSExport>

JSExportAs(postjsaction, -(void)postjsaction:(NSString *)name Scripts:(NSString *)action);
JSExportAs(alert, -(void)alert:(id)message);


@end

@protocol HQJSResultDelegate <NSObject>

-(void)receivejsaction:(NSString *)name Scripts:(NSString *)action;

@end

@interface HQJSInterface : NSObject<HQJSProtocal>

-(instancetype)initWithDelegate:(id<HQJSResultDelegate>)delegate;

@end
HQJSResultDelegate這個協議是用來回調傳遞HQJSProtocal協議方法接收到的資料的;

.m

#import "HQJSInterface.h"

@interface HQJSInterface()

@property (nonatomic , weak) id<HQJSResultDelegate> delegate;

@end

@implementation HQJSInterface
-(instancetype)initWithDelegate:(id<HQJSResultDelegate>)delegate{
    if (self = [super init]) {
        _delegate = delegate;
    }
    return self;
}

-(void)postjsaction:(NSString *)name Scripts:(NSString *)action{
    //nb
    if ([self.delegate respondsToSelector:@selector(receivejsaction:Scripts:)]) {
        [self.delegate receivejsaction:name Scripts:action];
    }
}
-(void)alert:(id)message{
    if ([message isKindOfClass:[NSString class]]) {
        NSLog(@"%@",message);

    }
}

@end

之後結合UIWebView使用:
- (void)webViewDidFinishLoad:(UIWebView *)webView{
    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    HQJSInterface * dtp = [[HQJSInterface alloc]initWithDelegate:self];
    self.context[@"dtp"] = dtp;
}

獲取上下文,註冊互動物件,通過HQJSResultDelegate的協議方法,我們就可以得到js呼叫所傳遞的資料了;

總結:

這種js互動的實踐,到是讓我重新認識了一下js與原生,聯想到了最近很火的ReactNative,移動端的開發對系統api及平臺的依賴性是必然的,但是新的程式設計框架也在改變著一些東西,之前有位朋友說他已經連續幾個月一直在用React這種方式程式設計了,不禁感嘆技術的跟新如此之快,以至於稍不留神就又被丟擲軌道的感覺,一開始的嘮叨多少和這個也有些關係,敢於嘗試新的東西,同時深入學習有所專攻,努力成長,迎接即將到來的2017。

參考文章:

http://www.jianshu.com/p/86a1b69bc9a6

http://www.jianshu.com/p/d19689e0ed83

http://www.tuicool.com/articles/qQRrMzY


相關推薦

IOS WebViewJS和OC相互呼叫

  現在有很多專案中都涉及到HTML5,在一個普通的APP裡面嵌入HTML5網頁,嵌入的這些網頁在伺服器把頁面修改之後同樣也能跟著修改,這樣就能很方便的修改程式的展示內容。如果使用tabelView或者其他的控制元件展示內容的話,當展示的內容的樣式需要發生改變的

iOS webviewjs 互動

1.先上一段 html 程式碼 <html> <head> <meta http-equiv="Content-Type"content="text/html; charset=utf8"> </head> &l

iOS WebViewJS互動

前言: 一段時間了,手頭的工作照常進行中,之前有好幾個主題一直想寫,但又擱置了,主要是主題有點大,看樣子路還是要一步一步走的; 前幾天,收到了一份面試通知,一家比較大的網際網路企業吧,想想自己也沒什麼面試經驗,總想著要換個環境,也想換個角度審視一下自己,所以就去了,真心是沒

AndroidWebviewjs互動

1.js呼叫Android程式碼Android端:webView.addJavascriptInterface(new WebHost(this),"js");向WebView註冊一個名叫“js”的物件,然後在JS中可以訪問js這個物件,呼叫這個物件裡的一些方法。 publi

ios webviewJS互動

最近寫了一個與JS互動的程式,瞭解了下HTML ,HTML DOM,JS相關的知識 1.什麼是 DOM? 通過 JavaScript,您可以重構整個 HTML 文件。您可以新增、移除、改變或重排頁面上的專案。 要改變頁面的某個東西,JavaScript 就需要獲

iOS webViewJS簡單互動處理

首先  url = @"http://42.96.155.42:8080/crm/loginRelationServlet?openId=A786D29EBAD81123313619A2F19B9447&accessToken=8F796D79CE14E4C5A7

WebViewjs和android互動遇到的坑

js呼叫Android程式碼 //android程式碼 private int load_state = -1;//記錄當前的載入狀態 private WebView mWebView; @SuppressLint("JavascriptInterface"

iOS UIWebViewJS和OC互相呼叫

最近做的專案中,是用html做的,我這邊直接用iOS原生的UIWebView進行載入顯示,在期間用到了js和OC的互相呼叫,這裡記錄下來      JS呼叫OC方法:         首先,什麼是JS呼叫O

Android之webViewjs互動

一、java呼叫js操作: 1.佈局檔案: <WebView android:id="@+id/web" android:layout_width="match_parent" android:layout_height="mat

webViewjs互動

1.匯入網路許可權 2.View佈局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res

解決Android簽名混淆後WebViewJS互動失效的問題

最近做了個網頁端微信支付的小功能,測試版還好好的,混淆打包後,寫的方法webview無法呼叫,意識到混淆除了問題,於是在網上找了一些大神的解決方案,再根據自己的實際解決過程,列出來一個完整的解決方法。 Android4.2以上版本呼叫js介面需要在方法使用宣告@JavascriptInterfa

WebViewJs互動所有方法及使用

首先 你肯定要定義,初始化一個webview,其實網上的例子很多,我這裡就簡單的把一些WebView 中可能會用到的的很重要的屬性以及支援全屏播放視訊該怎麼實現的程式碼粘出來,直接放到專案中去就行了 [java] view plaincopy <span style=

Android筆記之 WebviewJs互動-詳情舉例

Android呼叫網頁自身Js 你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Markdown的基本語法知識。 本地(asset)網頁androidcalljs.h

Webviewjs互動

public class MainActivity extends AppCompatActivity implements View.OnClickListener { private EditText ed; private Button btn; priva

webviewjs互動在targetsdkversion設定為19的時候出現的問題

轉自:http://blog.csdn.net/kaka123ac/article/details/42871441 1.在WebView中呼叫js,在4.4(target = 19)之前,只有一種方法:      呼叫js方法 test()     webView.lo

Android webViewjs互動

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layo

Android WebViewJS互動及訊息處理

一、WebView與JS互動 1.JS呼叫本地方法 這個功能的實現還是比較容易的。直接呼叫WebView的該方法就可以新增介面了,不過先要啟動互動 ? 1 2 3 4 // 啟用javascript  mWebView.getSettin

Android WebViewjs互動方式原理總結

webView.loadUrl("javascript:console(" + "'Hello,China!'" + ")""); 二、js注入實現 先來說說原理吧,當js呼叫prompt()方法時,WebChromeClient.onJsPrompt()方法會被觸發,當js觸發Android提供的介面方法時

Android webViewjs 互動以及jsbridge框架原始碼分析

1.簡單篇 如何實現簡單的android 呼叫js 與js呼叫android 讓webview做一下操作 private void init(Context context){ WebSettings setting =

WebViewJS互動不會執行onPageFinished() -WebView(WebKit)

WebView sample: https://github.com/GoogleChrome/chromium-webview-samples Android WebView 在開發過程中有哪些坑?->https://www.zhihu.com/question/3