首先介绍Android项目目录及文件作用

  1. res/layout/main.xml App主窗体布局文件,你的应用长什么样都在这边定义,有Design和Text两种模式
  2. res/values/strings.xml 可以理解为i18n文件,这个文件用来存放程序调用的各种字符串
  3. src/com/example/helloandroid/MyActivity.java 这个就是我们的主程序类,等下要实现的功能都在这个文件里添加
  4. 为应用添加一个idhellotextViewtextview和一个idhellobuttonbuttonmain.xml 代码如下:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:orientation="vertical"
    4. android:layout_width="fill_parent"
    5. android:layout_height="fill_parent"
    6. >
    7. <TextView
    8. android:layout_width="fill_parent"
    9. android:layout_height="180dp"
    10. android:text="@string/default_message"
    11. android:id="@+id/hellotextView" android:textColor="#00ff00" android:gravity="center"/>
    12. <Button
    13. android:layout_width="wrap_content"
    14. android:layout_height="wrap_content"
    15. android:text="@string/button_send"
    16. android:id="@+id/hellobutton" android:layout_gravity="center"/>
    17. </LinearLayout>
  5. strings.xml 代码和控件用到的字符串定义如下:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <resources>
    3. <string name="app_name">helloandroid by hiwanz</string>
    4. <string name="button_send">Say something</string>
    5. <string name="default_message">Click button below!</string>
    6. <string name="interact_message">You just clicked on the Button!</string>
    7. </resources>
  6. MyActivity.java 主程序中定义button点击后改变textview显示的文本,并且弹出Toast提示信息,代码如下: ```java package com.example.helloandroid;

import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast;

public class MyActivity extends Activity { /**

  1. * Called when the activity is first created.
  2. */
  3. @Override
  4. public void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.main);
  7. //得到按钮实例
  8. Button hellobtn = (Button)findViewById(R.id.hellobutton);
  9. //设置监听按钮点击事件
  10. hellobtn.setOnClickListener(new View.OnClickListener() {
  11. @Override
  12. public void onClick(View v) {
  13. //得到textview实例
  14. TextView hellotv = (TextView)findViewById(R.id.hellotextView);
  15. //弹出Toast提示按钮被点击了
  16. Toast.makeText(MyActivity.this,"Clicked",Toast.LENGTH_SHORT).show();
  17. //读取strings.xml定义的interact_message信息并写到textview上
  18. hellotv.setText(R.string.interact_message);
  19. }
  20. });
  21. }

}

  1. 有了以上的一些基本知识,来看混合开发目录结构就更清晰了。
  2. <a name="bJ5nz"></a>
  3. ### 混合开发Demo
  4. 地址[https://github.com/liulinboyi/HybridAppDemo](https://github.com/liulinboyi/HybridAppDemo)
  5. 使用`Android Studio`打开,里面用到了`gradle`需要使用国内镜像或者自行解决网络问题。
  6. 只要看这两个文件:
  7. <a name="PlMJ8"></a>
  8. #### MyJaveScriptInterface
  9. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/288075/1636634791588-107e8544-0d52-40a5-bad7-5a8c62ad1a06.png#clientId=u50804b9e-ee5f-4&from=paste&height=648&id=ue626214f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1296&originWidth=811&originalType=binary&ratio=1&size=99233&status=done&style=none&taskId=uff217d47-2eef-4cac-b55c-2b440461aaf&width=405.5)
  10. ```java
  11. package cn.sunday.hybridappdemo.jsInterface;
  12. import android.app.AlertDialog;
  13. import android.content.Context;
  14. import android.webkit.JavascriptInterface;
  15. import com.tencent.smtt.sdk.ValueCallback;
  16. import java.util.Timer;
  17. import java.util.TimerTask;
  18. import cn.sunday.hybridappdemo.views.X5WebView;
  19. //可以被Webview调用的安卓原生方法
  20. public class MyJaveScriptInterface {
  21. private Context mContext;
  22. private X5WebView mWebView;
  23. public MyJaveScriptInterface(Context context, X5WebView x5WebView) {
  24. this.mContext = context;
  25. this.mWebView = x5WebView;
  26. }
  27. /**
  28. * window.AndroidJSBridge.androidTestFunction1('xxxx')
  29. * 调用该方法,APP 会弹出一个 Alert 对话框,
  30. * 对话框中的内容为 JavaScript 传入的字符串
  31. *
  32. * @param str android 只能接收基本数据类型参数
  33. * ,不能接收引用类型的数据(Object、Array)。
  34. * JSON.stringify(Object) -> String
  35. * *重要*
  36. */
  37. @JavascriptInterface
  38. public void androidTestFunction1(String str/*安卓接收的参数只能是基本数据类型*/) {
  39. AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
  40. builder.setMessage(str);
  41. builder.setNegativeButton("确定", null);
  42. builder.create().show();
  43. }
  44. /**
  45. * 调用该方法,方法会返回一个返回值给 javaScript 端
  46. *
  47. * @return 返回值的内容为:"androidTestFunction2方法的返回值"
  48. */
  49. @JavascriptInterface
  50. public String androidTestFunction2() {
  51. return "androidTestFunction2方法的返回值";
  52. }
  53. }

MainActivity

image.png

  1. package cn.sunday.hybridappdemo;
  2. import android.app.AlertDialog;
  3. import android.os.Handler;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.os.Bundle;
  6. import android.util.JsonReader;
  7. import android.util.Log;
  8. import android.view.View;
  9. import com.tencent.smtt.export.external.interfaces.JsResult;
  10. import com.tencent.smtt.sdk.ValueCallback;
  11. import org.json.JSONException;
  12. import org.json.JSONObject;
  13. import cn.sunday.hybridappdemo.constants.Constants;
  14. import cn.sunday.hybridappdemo.views.X5WebView;
  15. public class MainActivity extends AppCompatActivity {
  16. private X5WebView mWebView;
  17. @Override
  18. protected void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. setContentView(R.layout.activity_main);
  21. init();
  22. }
  23. /**
  24. * 初始化 webview
  25. */
  26. private void init() {
  27. mWebView = findViewById(R.id.web_view);
  28. mWebView.loadUrl(Constants.WEB_URL);
  29. }
  30. /**
  31. * 原生端调用 web 方法,方法必须是挂载到 web 端 window 对象下面的方法。
  32. * 调用 JS 中的方法:onFunction1
  33. */
  34. public void onJSFunction1(View v) {
  35. mWebView.evaluateJavascript("javascript:onFunction('android调用JS方法')", new ValueCallback<String>() {
  36. @Override
  37. public void onReceiveValue(String s) {
  38. final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
  39. Log.d("onJSFunction1", s);//Debug 调试
  40. // https://stackoverflow.com/questions/10267910/jsonexception-value-of-type-java-lang-string-cannot-be-converted-to-jsonobject
  41. String json = s.substring(s.indexOf("{"), s.lastIndexOf("}") + 1).replace("\\\"", "\"");
  42. Log.d("处理之后", json);//Debug 调试
  43. JSONObject res = null;
  44. try {
  45. res = new JSONObject(json);
  46. boolean flag = res.optBoolean("status");
  47. String msg = res.optString("msg");
  48. if (flag) {
  49. builder.setMessage(msg);
  50. builder.setNegativeButton("确定", null);
  51. builder.create().show();
  52. }
  53. } catch (JSONException e) {
  54. e.printStackTrace();
  55. }
  56. // 定时
  57. // Handler handler = new Handler();
  58. // handler.postDelayed(new Runnable() {
  59. // @Override
  60. // public void run() {
  61. // builder.create().show();
  62. // }
  63. // }, 1000);
  64. }
  65. });
  66. }
  67. }

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <input type="button" value="js调用android方法1" onclick="onAndroidFunction1('js调用android方法1')">
  11. <input type="button" value="js调用android方法2" onclick="onAndroidFunction2()">
  12. <br>
  13. <input type="button" value="js调用IOS方法1" onclick="onIOSFunction1('js调用ios方法1')">
  14. <input type="button" value="js调用IOS方法2" onclick="onIOSFunction2()">
  15. <script>
  16. // 调用 Android 方法1
  17. function onAndroidFunction1(str) {
  18. window.AndroidJSBridge.androidTestFunction1(str);
  19. }
  20. // 调用 Android 方法2
  21. function onAndroidFunction2() {
  22. var result = window.AndroidJSBridge.androidTestFunction2();
  23. alert(result);
  24. }
  25. // Android 调用 onFunction 方法
  26. window.onFunction = function (str) {
  27. // alert(str);
  28. result = window.confirm("hello");
  29. let res = JSON.stringify({
  30. status: result,
  31. msg: 'onFunction 方法已经调用完成 此消息来自Webview\n'
  32. });
  33. console.log(res)
  34. return res;
  35. }
  36. // ----------------------
  37. // 调用 IOS 方法1
  38. function onIOSFunction1(str) {
  39. window.webkit.messageHandlers.IOSTestFunction1.postMessage({
  40. msg: str
  41. });
  42. }
  43. // 调用 IOS 方法2
  44. function onIOSFunction2() {
  45. window.webkit.messageHandlers.IOSTestFunction2.postMessage({});
  46. }
  47. // IOS 回调 onFunctionIOS 方法
  48. window.onFunctionIOS = function (str) {
  49. alert(str);
  50. return 'onFunctionIOS 方法已经调用完成';
  51. }
  52. </script>
  53. </body>
  54. </html>