为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第20天 2小时搞定移动端混合开发基础入门 课程全集

标签:
Android iOS WebApp

课程章节: 课程全集

主讲老师: whinc

课程内容:

今天学习的内容包括:

JSBridge 实现原理;

JSBridge 实现方式:

  1. 拦截 URL Schema
  2. 注入 JS API

Web 端如何发送原生 HTTP 请求

课程收获:

问答:

问题:webView.evaluateJavascript报错:webView.evaluateJavascript(jsCode, resultCallback:null);
回答:resultCallback:不要填写

问题:Chrome如何调试Android WebView
回答:第一次打开 DevTools 需要访问 Google Chrome 下载设备相关文件

课程实例:
/jsbridge-principle/web/index.html

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      font-size: 50px;
    }
  </style>
  <script>
    window.showWebDialog = text => window.alert(text);
    document.addEventListener('DOMContentLoaded', e => {
      const editText = document.querySelector('#editText');
      const showBtn = document.querySelector('#showBtn');
      showBtn.addEventListener('click', e => {
        const inputValue = editText.value;
        showNativeDialog(inputValue)
      })
    })

    function showNativeDialog (text) {
      // window.alert('jsbridge://showNativeDialog?text=' + text);
      window.NativeBridge.showNativeDialog(text);
    }
  </script>
</head>
<body>
  <div>
    <input id="editText" type="text" placeholder="输入内容" />
  </div>
  <div>
    <button id="showBtn">显示Native弹窗</button>
  </div>
</body>
</html>

/jsbridge-principle/native/app/src/main/java/com/example/jsbridge/MainActivity.java

package com.example.jsbridge;

import androidx.appcompat.app.AppCompatActivity;

import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;

import java.util.Date;

public class MainActivity extends AppCompatActivity {

    private WebView webView;
    private EditText editText;
    private Button showBtn;
    private Button refreshBtn;
    private MainActivity self = this;

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

        webView = findViewById(R.id.webView);
        editText = findViewById(R.id.editText);
        showBtn = findViewById(R.id.showBtn);
        refreshBtn = findViewById(R.id.refreshBtn);

        webView.loadUrl("http://10.43.101.59:18929?timestamp=" + new Date().getTime());
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebChromeClient(new WebChromeClient());
        webView.addJavascriptInterface(new NativeBridge(this), "NativeBridge");

        showBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String inputValue = editText.getText().toString();
                self.showWebDialog(inputValue);
            }
        });

        refreshBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                webView.loadUrl("http://10.43.101.59:18929?timestamp=" + new Date().getTime());
            }
        });
    }

    private void showWebDialog (String text) {
        String jsCode = String.format("window.showWebDialog('%s')", text);
        webView.evaluateJavascript(jsCode, null);
    }

//    private void showNativeDialog(String text) {
//        new AlertDialog.Builder(this).setMessage(text).create().show();
//    }

    class NativeBridge {
        private  Context ctx;
        NativeBridge(Context ctx) {
            this.ctx = ctx;
        }

        @JavascriptInterface
        public void showNativeDialog(String text) {
            new AlertDialog.Builder(ctx).setMessage(text).create().show();
        }
    }
}

/hybrid-app/web/index.html

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>demo</title>
  <style>
    * {
      font-size: 50px;
    }
  </style>
  <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://unpkg.com/dsbridge@3.1.3/dist/dsbridge.js"> </script>
  <script>
    document.addEventListener('DOMContentLoaded', e => {
      const urlTextEl = document.querySelector('#urlText')
      const sendBtn = document.querySelector('#sendBtn')
      const responseEl = document.querySelector('#response')
      sendBtn.addEventListener('click', e => {
        const url = urlTextEl.value
        if (url) {
          // 清除旧数据
          responseEl.textContent = ''
          // 发送原生请求
          dsBridge.call("nativeRequest", {url: url}, data => {
            responseEl.textContent = data
          })
        }
      })
    })

    dsBridge.register("changeTheme", color => {
      // android  0xFFFF0000   ARGB
      // web 0xFF0000FF  RGBA
      document.body.style.backgroundColor = '#' + (color & 0x00FFFFFF).toString(16)
    })
  </script>
</head>
<body>
  <div>
    <input id="urlText" type="text" value="http://www.google.com" />
    <button id="sendBtn">发送请求</button>
  </div>
  <div>
    <p>请求返回:</p>
    <p id="response"></p>
  </div>
</body>
</html>

/native/app/src/main/java/com/example/demo/MainActivity.java

package com.example.demo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import wendu.dsbridge.CompletionHandler;
import wendu.dsbridge.DWebView;

public class MainActivity extends AppCompatActivity {

    private DWebView webView;

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

        webView = findViewById(R.id.webView);
        webView.addJavascriptObject(new JsApi(), null);
        webView.loadUrl("http://10.43.101.59:8080");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        changeTheme(0xFFFF0000);
        return true;
    }

    // 换肤
    private void changeTheme (int color) {
       // 状态栏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        getWindow().setStatusBarColor(color);

        // 标题栏
        getSupportActionBar().setBackgroundDrawable(new ColorDrawable(color));

        // 导航栏
        getWindow().setNavigationBarColor(color);

        // Web 网页的背景
        webView.callHandler("changeTheme", new Object[]{color});
    }

    public class JsApi {
        @JavascriptInterface
        public void nativeRequest(Object params, CompletionHandler handler) {
            try {
                String url = ((JSONObject)params).getString("url");
                String data = request(url);
                handler.complete(data);
            } catch (Exception e) {
                handler.complete(e.getMessage());
                e.printStackTrace();
            }
        }

        private String request(String urlSpec) throws Exception {
            HttpURLConnection connection = (HttpURLConnection) new URL(urlSpec).openConnection();
            connection.setRequestMethod("GET");
            InputStream inputStream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuffer result = new StringBuffer();
            String line;
            while((line = reader.readLine()) != null) {
                result.append(line);
            }
            reader.close();
            connection.disconnect();
            return result.toString();
        }
    }
}

图片描述

图片描述

图片描述

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消