移動應用程序開發中,有一種情況是用戶希望將他們的交互式 Web 內容作為原生 Android 或 iOS 應用程序。 為此,開發人員有 2 個選項,他們可以從頭開始構建應用程序,這需要額外的時間和資源,或者是將網頁作為 web 視圖嵌入到原生 android 應用程序中的最簡單和更快的選項。 它將減少開發人員開發本機應用程序 UI 并僅使用當前網頁中的 UI 的時間。
但是,這種方法存在局限性,例如某些任務或手勢只能在移動應用程序中發生,而不能在瀏覽器中發生,例如語音命令或滑動手勢。 為了適應這一點,我們需要在原生應用程序中添加額外的代碼,并將這個原生任務連接到我們的 webview 應用程序。 在這種情況下,javascript 注入作為將本機代碼(Java 或 Swift)橋接到網頁代碼(Javascript)的解決方案
Android 中的 Javascript 注入
在這里,我將嘗試解釋在 Native android 應用程序中加載網頁所需完成的基本設置。首先,您需要在活動布局中設置 webview,下面是如何在 Android XML 文件中添加 <Webview> 標記的示例
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
之后,我們需要訪問互聯網才能在我們的應用程序中工作,為此我們應該在 Android 清單文件中添加以下語法
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
現在,我們可以移動到 MainActivity.java 文件,在這里我們需要在 onCreate() 函數中添加以下語法。因為 onCreate 函數是我們初始化一切的第一個地方,所以下面的語法幫助我們初始化我們的 webview。 setJavaScriptEnabled(true) 語法需要設置為 true,以授予在此使用 javascript 注入的權限。 addJavascriptInterface(this,"android") 語法將有助于創建可用作 Java 和 Javascript 之間的橋梁的 Web 界面。在這里,我們的界面將被稱為android。最后一個語法是 loadUrl ,它有助于在 Native 應用程序中加載我們的網頁。
WebView webViewMain;
webViewMain=findViewById(R.id.webview);
webViewMain.getSettings().setJavaScriptEnabled(true);
webViewMain.addJavascriptInterface(this, "android");
webViewMain.loadUrl("https://www.example.com");
仍然在 MainActivity.java 文件中,我們需要在 onCreate() 函數之外添加一個類。這個類將存儲我們想要在 javascript 中運行的所有函數,我們也可以從 javascript 中獲取任何值以傳輸到 Java 原生應用程序變量。示例之一是 getId 函數,它將 HTML 標簽中的 id 傳輸到本地應用程序中進行識別。
public class WebAppInterface {
String value="hello"
@JavascriptInterface
public String runValue() {
return value;
}
@JavascriptInterface
public int getId(id) {
return id;
}
}
要使用上述函數,下面是我們可以在 onCreate() 或其他偵聽器函數中添加的語法。您可以識別出我們使用 loadUrl 來注入 javascript,在 loadurl 中我們可以使用每種 javascript 語法來導出網頁。同樣在 loadurl 中,我們需要添加上面已經創建的函數,并將 android 作為父函數。
webViewMain.loadUrl("javascript:window.onclick=function(e) {\n" +
"android.getId(e.target.id);}");
webViewMain.loadUrl("javascript:android.getSpeechIndex()");
關注七爪網,獲取更多APP/小程序/網站源碼資源!
最近開始重新關注SEO,也對網站做了一下優化整理,期間遇到了一些問題,這里簡單記錄下。希望能對有同樣問題的人有所幫助。流水賬而已也沒啥特別好說的...
我們知道在使用Nuxt進行SSR后,網站會啟用服務端渲染,然后進行前端頁面展示。最近因為關注SEO所以看了下我的網頁源代碼。
我的天啊,真的是不看不知道一看慘不忍睹,下面上一個直觀圖:
這還只是冰山一角!頁面中充斥著大量的css樣式。
我們正常的前端項目是會有一個個的css和js文件,但是Nuxt項目在經過webpack打包后整合到了一起。從上圖中紅色標注中我們可以看到。這是把element-ui的組件中的樣式全部整合進來了。
我們知道網絡爬蟲在爬取你的網頁數據時不能進行JS的動態編譯,但是像上述中這一坨css是可以被爬取的。
于是乎,爬蟲的到的網頁源代碼就包含了這些無用信息(對于爬蟲來說是無用的,會降低他們對網頁質量的判斷),同樣會印象網站的響應速度這樣是不利于網站做SEO的!
其實這個網頁源代碼中被嵌入css的問題可以通過一個配置進行解決!talk is cheap show me your code!
// 將內嵌CSS樣式提取到外部
extractCSS: { allChunks: true },
Java
我們只需要再Nuxt.config中加入以上配置就可以使得html和css進行分離了!
瞬間清新整潔了不少哈!
在SEO中是要好好使用h1、h2這些標簽的,至于原因我們下期詳細講講...
比于 Native App 和 Web App,Hybrid App 憑借其迭代靈活、控制自如、多端同步的優勢在應用市場上越發顯得優勝,主要得力于,其將變更頻繁的部分產品功能使用 H5 開發并在客戶端中借助 WebView 控件嵌入應用當中。所以,開發中我們總會遇到原生 Java 代碼與網頁中的 Js 代碼之間相互調用從而產生的交互問題。
Java 與 Js 彼此調用的前提是設置 WebView 支持 JavaScript 功能:
第一步,在網頁中使用 Js 定義提供給 Java 訪問的方法,就像普通方法定義一樣,如:
第二步,在 Java 代碼中按照 “javascript:XXX” 的 Url 格式使用 WebView 加載訪問即可:
注意:String 類型的參數需要使用單引號 “’” 包裹,數組類型的參數則不用,如:javascript:javaCallJs([01, 02, 03]),其他復雜類型的參數可以轉換為 Json 字符串的形式傳遞。
第一步,在 Java 對象中定義 Js 訪問的方法,如:
注意事項:提供給 Js 訪問的屬性和方法必須定義為 public 類型,并且添加注解 @JavascriptInterface。在 API 17 及更高版本的系統中,任何暴露給 Js 訪問的 Java 接口都需要添加這個注解,否則會報異常:Uncaught TypeError: Object [object Object] has no method ‘XXX’。系統這種做法也是為了降低應用的安全隱患,因為在之前的版本中,Js 可以通過反射的方式訪問注入 WebView 中的 Java 對象的 public 類型 field 和 method,從而隨意修改宿主程序。
第二步,將提供給 Js 訪問的接口內容所屬的 Java 對象注入 WebView 中:
addJavascriptInterface(Object object, String name) 參數說明:object 表示 Js 訪問的接口內容所在的 Java 對象;name 表示 Js 調用 Java 代碼時的接口名稱,與 Js 中的調用保持一致即可。
第三步,Js 按照指定的接口名訪問 Java 代碼,有如下兩種寫法:
這里簡單提供一個可供測試的 Html 網頁和 Activity 代碼:
test.html:
MainActivity.java:
效果圖:
注意:無論是 Java 調用 Js 還是 Js 調用 Java,只能通過參數傳遞數據,而無法獲取彼此方法的返回值!解決方案就是額外添加一層回調來達到這個目的。比如 Java 調用 Js 的方法,Js 計算結束所得結果不能通過 return 語句返回給 Java 調用者,而是再回調 Java 的另一個方法,通過傳參的形式傳遞給 Java。
1.使用 loadUrl() 方法實現 Java 調用 Js 功能時,必須放置在主線程中,否則會發生崩潰異常。比如修改上面的代碼:
運行時會得到如下 logcat 異常信息:
java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'Thread-18022'. All WebView methods must be called on the same thread.
如果真的在子線程中遇到調用 Js 的功能,也要將其轉換到主線程中去:
2.Js 調用 Java 方法時,不是在主線程 (Thread Name:main) 中運行的,而是在一個名為 JavaBridge 的線程中執行的,通過如下代碼可以測試:
所以這里需要注意的是,當 Js 調用 Java 時,如果需要 Java 繼續回調 Js,千萬別在 JavascriptInterface 方法體中直接執行 loadUrl() 方法,而是像前面一樣進行線程切換操作。
3.代碼混淆時,記得保持 JavascriptInterface 內容,在 proguard 文件中添加如下類似規則 (有關類名按需修改):
除了上面這種 Java 與 Js 互調方法的方式,還可以利用 WebView 攔截 Url 的方式實現原生應用與 H5 之間的交互動作。通過 WebViewClient 提供的接口攔截網頁內諸如二級跳轉的 Url 鏈接,便可以進行業務邏輯上的判斷處理、Url 參數傳遞等功能,如:
注意:過去常用的 shouldOverrideUrlLoading(WebView view, String url) 方法已經被廢棄。
通過 Java 與 Js 之間的交互可以做很多事情,比如獲取網頁中的圖片,利用原生控件予以展示,類似響應微信公眾號文章中的圖片點擊事件。參考代碼如下:
作者博客地址:
http://yifeng.studio/2016/12/01/android-webview-java-js-interaction
*請認真填寫需求信息,我們會在24小時內與您取得聯系。