需求: 本人前端想用 android 打开 h5 页面,可以发送ajax 进行通信。于是查到用 nanoHTTPD 创建简单http服务器。 想着用webView 打开 assets 下的 html 页面     

file:///android_asset/www/login.html"

再发送ajax 与服务器(http://127.0.0.1:9999)进行通信,但出现跨域的问题。

      于是 nanoHTTPD 服务器打开 html,然后用 webView 打开就没有跨域的问题。先这样,然后再去解决跨域的问题

项目目录:

 build.gradle(Module:app)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.httpdemo"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    implementation'org.nanohttpd:nanohttpd:2.3.1'
}

 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.httpdemo">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

  HttpService.java

package com.example.httpdemo;
import android.content.res.AssetManager;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.util.Map;
import fi.iki.elonen.NanoHTTPD;

public class HttpService extends NanoHTTPD {
    AssetManager asset = null;
    public HttpService(int host) {
        super(host);
    }

    public NanoHTTPD.Response serve(NanoHTTPD.IHTTPSession iHTTPSession) {
        //获取参数
        Map parms = iHTTPSession.getParms();
        System.out.println(parms);
        System.out.println("iHTTPSession.getUri()=== " + iHTTPSession.getUri());
        String filename = iHTTPSession.getUri();
        if (iHTTPSession.getUri().equals("/")) {
            System.out.println("111 " + asset);
            return index("/login.html");
        } else if(filename.contains(".js")){
            System.out.println("222 " + asset);
            return index(filename);
        }
        return newFixedLengthResponse("500");
    }

    private NanoHTTPD.Response index(String filename) {
        //加载Assets里的html文件
        return NanoHTTPD.newFixedLengthResponse(getIndex(filename));
    }

    public String getIndex(String filename) {

        InputStream inputStream = null;
        InputStreamReader isr = null;
        BufferedReader br = null;

        StringBuffer sb = new StringBuffer();
        try {
            inputStream = asset.open("www" +filename);
            isr = new InputStreamReader(inputStream);
            br = new BufferedReader(isr);

            sb.append(br.readLine());
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append("\n" + line);
            }

            br.close();
            isr.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return sb.toString();
    }
}

MainActivity.java

package com.example.httpdemo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity {
    //创建服务
    HttpService http=new HttpService(9999);

    private WebView webView;
    private boolean isSuccess = false;
    private boolean isError = false;

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

        //服务启动
        http.asset=getAssets();//传递assets对象
        try {
            http.start();

//            setUpView("file:///android_asset/www/login.html");
            setUpView("http://127.0.0.1:9999/");

        }catch (Exception e ){
            System.out.print(e);
        }


    }

    @SuppressLint("SetJavaScriptEnabled")
    public void setUpView(String url) {
        //加载需要显示的网页
        webView = new WebView(this);
        WebSettings webSettings = webView.getSettings();
        webView.loadUrl(url);
        webSettings.setJavaScriptEnabled(true);  //设置WebView属性,运行执行js脚本
        webSettings.setDomStorageEnabled(true);
        webSettings.setUseWideViewPort(true);//设定支持viewport
        webSettings.setLoadWithOverviewMode(true);   //自适应屏幕
        webSettings.setBuiltInZoomControls(true);
        webSettings.setDisplayZoomControls(false);
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setSupportZoom(true);//设定支持缩放
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//不读取缓存
        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        webView.setBackgroundColor(ContextCompat.getColor(this,android.R.color.transparent));
//        webView.setBackgroundResource(R.color.black);
        webView.setWebViewClient(webClient);  //设置Web视图
        webView.setWebContentsDebuggingEnabled(true);
    }

    WebViewClient webClient = new WebViewClient() {
        //设置打开网页时,不调用系统浏览器进行打开,而是在本WebView中直接显示。
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            isError = false;
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            isError = false;
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (!isError) {
                isSuccess = true;
                System.out.println("网页打开成功");
                setContentView(webView);
                //回调成功后的相关操作
            } else {
                isError = false;
                isSuccess = false;
                System.out.println("网页打开失败");
                startActivity(new Intent(MainActivity.this, MainActivity.class));
                Toast.makeText(MainActivity.this, "提示:连接失败,请检查地址及网络设置后重试(Connection failed. Please check the address and network settings and try again)。", Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);

            System.out.println("资源加载和页面打开错误时都会进入");
            //回调失败的相关操作
        }

        @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {
            isError = true;
            System.out.println("wifi webView页面打不开错误进入 直接在这打开页面会先进一个错误的页面 一晃");
        }
    };

    //安卓销毁事件
    @Override
    protected void onDestroy() {
        super.onDestroy();
        http.stop();
    }

}

login.html 

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
<!--    <meta http-equiv="Access-Control-Allow-Origin" content="*" />-->

    <script src="js/lib/jquery-2.1.4.js"></script>
</head>
<body>

<script type="text/javascript">

function modifyText() {
    console.log("ssssqqqq loadXMLDoc");
    $("#myDiv").text("loadXMLDoc");
}
</script>

<div id="myDiv"><h2>点击 修改该文本内容</h2></div>
<button type="button" id="btn" onclick="modifyText()">修改内容</button>
</body>
</html>


效果: 

 

 示例代码:

https://download.csdn.net/download/qq_40015157/86248291

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐