Android混合開發快速上手掌握

目錄

一 混合開發簡介

二 Android-Js互調

2.1 準備自己的html文件

2.2 WebView控件的準備設置

2.3 Android調用Js代碼

2.4 Js調用Android方法和傳參數

三 常用的幾個方法和注意點

3.1 WebViewClient中的shouldOverrideUrlLoading攔截url

3.2 WebViewClient中的onPageStarted

3.3 WebViewClient中的onPageFinished

3.4 webview的evaluateJavascript方法


先上效果圖:

源碼地址:https://github.com/LucasXu01/Autils

一 混合開發簡介

原生app :java/kotlin 純原生寫出的app;

web app:web寫出的app;

hybird app:原生+web(通過webview)寫出的app;

當然,現在也有很多第三方混合開發框架以及簡便的js橋,但是作爲最基礎的webview,掌握js/android的互調等相關知識是非常必要的。


二 Android-Js互調

2.1 準備自己的html文件

安卓和html中js的互調,一是要有安卓代碼,二肯定需要html網頁。工程中,網頁都是放在服務器,方便隨時更改,用戶無需再次更新自己的app,已達到hybrid開發的目的,實例方便起見,將html文件放在了本地。

首先,在自己安卓項目中的app目錄下新建assets文件夾(若沒有):

接着,在assets文件夾下新建自己的html文件,代碼如下:

<html>
    <head>
        <meta http-equiv="Content-Type" charset="GB2312"/>

        <script type="text/javascript">
            function javacalljs(){
                 document.getElementById("showmsg").innerHTML = "JAVA調用了JS的無參函數";
            }

            function javacalljswith(arg){
                 document.getElementById("showmsg").innerHTML = (arg);
            }

        </script>

    </head>

    <body>
        <h3 align="center">Web模塊</h3>

        <h3 id="showmsg" align="center">調用js顯示結果</h3>

        <div style="text-align:center; vertical-align:middle;">
            <input  type="button" value="Js調用Java代碼" οnclick="window.android.jsCallAndroid()"/>
        </div>

        <br>

        <br>

        <div style="text-align:center; vertical-align:middle;">
        <input  type="button" value="Js調用Java代碼並傳參數" οnclick="window.android.jsCallAndroidArgs('Js傳過來的參數')"/>
        </div>

    </body>
</html>

 

2.2 WebView控件的準備設置

在自己的activity活動中獲得webview控件後,需要進行以下設置:

WebSettings webSettings = webview.getSettings();
//與js交互必須設置
webSettings.setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/html.html");
webview.addJavascriptInterface(MainActivity.this,"android");
  • webSettings.setJavaScriptEnabled(true) 表示讓WebView支持調用Js;
  • webview.loadUrl("file:///android_asset/html.html") 表示加載assets文件下的html.html文件(因爲沒有網絡地址所以加載的本地文件)
  • webview.addJavascriptInterface(MainActivity.this,"android") 給webview添加Js調用接口,第一個參數爲類對象,第二個參數爲自定義別名,Js通過這個別名來調用Java的方法,我這裏自定義爲android。
    html中用到:<input type="button" value="Js調用Java代碼" οnclick="window.android.jsCallAndroid()"/>

2.3 Android調用Js代碼

在android代碼中(如按鈕點擊事件中),通過webview這個中介調用loadUrl來執行html代碼中的Js代碼:

 tvJs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webview.loadUrl("javascript:javacalljs()");
            }
        });

下爲html中要被安卓調用的js函數代碼,函數意圖爲:向id爲showmsg的h3大小標題中寫入字符串“JAVA調用了JS的無參函數”。

function javacalljs(){
                 document.getElementById("showmsg").innerHTML = "JAVA調用了JS的無參函數";
            }

在上述基礎上,若要在Android調用Js函數時傳參數,只需要在loadUrl方法中進行字符串的拼接,將參數以字符串形式拼接進去即可。

webview.loadUrl("javascript:javacalljswith(" + "'Android傳過來的參數'" + ")");

2.4 Js調用Android方法和傳參數

點擊html按鈕,通過οnclick="window.android.jsCallAndroid()事件,通過android別名調用Java文件的jsCallAndroid()方法。曾經Js可直接調用Java代碼竊取App信息,爲安全起見,在Android4.4以上並且必須加入@JavascriptInterface纔有響應。

@JavascriptInterface
    public void jsCallAndroid(){
        tvShowmsg.setText("Js調用Android方法");
    }

    @JavascriptInterface
    public void jsCallAndroidArgs(String args){
        tvShowmsg.setText(args);
    }

所有的activity代碼如下:

package com.lucas.autils.autils;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;

/**
 * 原生webview  js與安卓互調
 * @author lucas
 * created at 2019/9/12 12:23 PM
 */
public class JsJavaActivity extends Activity {

    private WebView webview;
    private TextView tvJs;
    private TextView tvJsArgs;
    private TextView tvShowmsg;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jsjava);

        setWebview();
        initView();
    }


    private void initView() {
        tvJs = (TextView) findViewById(R.id.tv_androidcalljs);
        tvJsArgs = (TextView) findViewById(R.id.tv_androidcalljsargs);
        tvShowmsg = (TextView) findViewById(R.id.tv_showmsg);

        tvJs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webview.loadUrl("javascript:javacalljs()");
            }
        });

        tvJsArgs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webview.loadUrl("javascript:javacalljswith(" + "'Android傳過來的參數'" + ")");
            }
        });
    }


    private void setWebview() {
        webview = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = webview.getSettings();
        webSettings.setBuiltInZoomControls(true);
        webSettings.setSupportZoom(true);
        //與js交互必須設置
        webSettings.setJavaScriptEnabled(true);
        webview.loadUrl("file:///android_asset/html.html");
        webview.addJavascriptInterface(JsJavaActivity.this,"android");
    }



    @JavascriptInterface
    public void jsCallAndroid(){
        tvShowmsg.setText("Js調用Android方法");
    }

    @JavascriptInterface
    public void jsCallAndroidArgs(String args){
        tvShowmsg.setText(args);
    }

}

三 常用的幾個方法和注意點

3.1 WebViewClient中的shouldOverrideUrlLoading攔截url

安卓webview中setWebViewClient方法中需要一個WebViewClient對象,而WebViewClient中有個方法爲shouldOverrideUrlLoading,通過此方法可以進行我們需要跳轉的url地址的攔截,並根據我們需要進行自定義化的一些操作,解析url做相應的事情。

3.2 WebViewClient中的onPageStarted

onPageStarted會在webview加載相應的url開始之前進行調用,常用來處理需要在加載相應url之前的一些操作。

3.3 WebViewClient中的onPageFinished

onPageStarted會在webview加載相應的url結束之後進行調用,常用來處理需要在加載相應url之後的一些操作,比如加載後更加網頁標題填充原生頁面最上方的活動標題。

3.4 webview的evaluateJavascript方法

該方法的執行不會使頁面刷新,而方法(loadUrl )的執行則會使頁面刷新。此Android 4.4 後纔可使用。

//攔截url
        webview.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (url.indexOf("jump")>-1){
                    Toast.makeText(JsJavaActivity.this,"攔截到了相應url",Toast.LENGTH_LONG).show();
                    return true;
                }else if (url.startsWith("http")){
                    view.loadUrl(url);
                    return true;
                }
                return false;
            }


            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                // 開始加載頁面時
            }



            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // 加載結束

                //因爲該方法的執行不會使頁面刷新,而方法(loadUrl )的執行則會使頁面刷新。
                //Android 4.4 後纔可使用
                webview.evaluateJavascript("javascript:changename()", new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        //此處爲 js 返回的結果
                        Log.v("Native",value);
                    }
                });


            }

        });

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章