1       Android加载HTML页面

1.1    WebView简介与使用

1.    Webview的应用场景

WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理,主要用于html页面的加载。

2.    WebView的使用步骤

(1)  在xml布局中创建对应的webview控件

                                               Android混合开发详解-LMLPHP

(2)  代码中通过findViewByid找出对应的控件

  Android混合开发详解-LMLPHP

(3)  Webview通过地址URL加载网页

// 1. 直接加载一个网页

webview.loadUrl("http://baidu.com");

注意:采用上面的方式加载网页,系统会重新打开浏览器加载网页,用户体验不好,需要进行以下设置

//2.处理跳转打开新的浏览器的问题setWebViewClient
     webview.setWebViewClient(
             new WebViewClient() {
                 @Override
   public boolean shouldOverrideUrlLoading(WebView view, String url) {
       view.loadUrl(url);
        //3.告诉系统不要打开新的浏览器了自己处理页面
         return true;
                 }
             }
     );
     //4.网页控件默认不支持JavaScript 需要用户打开支持的开关
     webview.getSettings().setJavaScriptEnabled(true);
     //5.网页控件默认不支持弹出框 alert() prompt() confirm()...
     // 但是Html5的弹出框是默认支持的設置setWebChromeClient
     webview.setWebChromeClient(new WebChromeClient() {
         @Override
         public boolean onJsAlert(WebView view, String url, String   message, JsResult result) {
             return super.onJsAlert(view, url, message, result);
         }
     });
 }

(4)  WebView加载本地html页面

首先需要在Android项目的src—main包下面创建assets文件夹,将对应的html放入其中,如下图所示:

Android混合开发详解-LMLPHP

// 加载本地的网页 
webview.loadUrl("file:///android_asset/webview.html"); 

(5)  WebView直接加载html代码的两种方式

Android混合开发详解-LMLPHP

LoadData与LoadDataWithBaseURL的区别是什么?

两个方法加载的HTML代码片段有些不同,loadData()中的html data中不能包含'#', '%', '\', '?'四中特殊字符,这就为内嵌css等制造了些许麻烦,因为css中经常用'#', '%'等字符,需要用UrlEncoder编码为%23, %25, %27, %3f

在使用loadDataWithBaseURL时,需要注意的就是 baseUr:虽然API上写的是要传一个Url,但我在用时,发现传一个Url并不可以,我发现这个就是一个标志位,用来标志当前页面的Key值的,而historyUrl就是一个value值,在加载时,它会把baseUrl和historyUrl传到List列表中,当作历史记录来使用,当前进和后退时,它会通过baseUrl来寻找historyUrl的路径来加载historyUrl路径来加载历史界面,需要注意的就是history所指向的必须是一个页面,并且页面存在于SD卡中或程序中(assets),loadDataWithBaseURL,它本身并不会向历史记录中存储数据,要想实现历史记录,需要我们自己来实现,在加载页面时,把数据另外的写到一个html页面中,并把它保存到SD中,当点击返回时,它会通过historyUrl指向的路径来加载页面,这样就解决了历史记录问题

2        HTML与原生Android交互

2.1     HTML页面调用java中的方法

案例以本地的HTML页面为例进行讲解

(1)  在Android中创建供js调用的类和方法

Android混合开发详解-LMLPHP

(2)  在加载网页的时候需要进行相应的设置

Android混合开发详解-LMLPHP

(3)  在js中调用Android中方法的方式

在js中通过myObj调用本地的方法

Android混合开发详解-LMLPHP

2.2     Android中调用HTML中的js代码

   Android混合开发详解-LMLPHP

注意:以上方法能够调用的前提是webview已经把对应的网页加载进来了

Js中对应的方法如下:

Android混合开发详解-LMLPHP

3       WebView常用方法细节剖析

3.1    给webView添加header信息的方式

复写loadUrl()方法

@Override   public void loadUrl(String url) {

      Map map = new   HashMap();     
           map.put("ajax", "true");     
           map.put("appversion",   SharedPreferencesUtil.getAppVersion(getContext()));    

map.put("clientid",   SharedPreferencesUtil.getClientId(getContext()));

      loadUrl(url, map);

 }

 

3.2    Websettings详解

1. 打开网页时不调用系统浏览器, 而是在本WebView中显示:

mWebView.setWebViewClient(new WebViewClient(){

       @Override

       public boolean shouldOverrideUrlLoading(WebView view, String url) {

            view.loadUrl(url);

            return true;

      }

  });

 

2. 通过java代码调用javascript

WebSettings webSettings =   mWebView .getSettings();      

webSettings.setJavaScriptEnabled(true);

mWebView.addJavascriptInterface(new Object()   {      

             public void clickOnAndroid() {        

                 mHandler.post(new Runnable() {        

                    public void run() {      

                        webview.loadUrl("javascript:wave()");         

                    }      

                  });      

              }      

          }, "demo");

 

3. 按返回键时, 不退出程序而是返回上一浏览页面:

public boolean onKeyDown(int keyCode, KeyEvent   event) {      

          if ((keyCode == KeyEvent.KEYCODE_BACK) &&   mWebView.canGoBack()) {      

              mWebView.goBack();      

              return true;      

          }      

        return super.onKeyDown(keyCode, event);      

    }

 

4. 打开页面时,自适应屏幕:

WebSettings webSettings = mWebView   .getSettings();      

webSettings.setUseWideViewPort(true);//设置此属性,可任意比例缩放

webSettings.setLoadWithOverviewMode(true);

 

5. 页面支持缩放:

WebSettings webSettings = mWebView   .getSettings();      

webSettings.setJavaScriptEnabled(true); 

webSettings.setBuiltInZoomControls(true);

webSettings.setSupportZoom(true);

 

6.如果webView中需要用户手动输入用户名、密码或其他,则webview必须设置支持获取手势焦点。

webview.requestFocusFromTouch();

 

3.3         WebviewClient方法详解

WebviewClient常用方法:

1、shouldOverrideUrlLoading(WebView view, String url)

在API 24以后过时,当一个url即将被webview加载时,给Application一个机会来接管处理这个url,方法返回true代表Application自己处理url;返回false代表Webview处理url。举个例子,项目中需要处理传过来的URL是一个事件还是一个HTTP链接,可以通过自定义协议头 (nativeapi://) 来过滤,如:

@Override

public boolean   shouldOverrideUrlLoading(WebView view, String url) {

    Uri   uri = Uri.parse(url);

       String scheme = uri.getScheme();      

              if (TextUtils.isEmpty(scheme)) return true;    

            if (scheme.equals("nativeapi")) {        

             //如定义nativeapi://showImg是用来查看大图,这里添加查看大图逻辑

           return true;

     }   else if (scheme.equals("http") || scheme.equals("https"))   {        

              //处理http协议

           if (Uri.parse(url).getHost().equals("www.example.com"))   {           

              // 内部网址,不拦截,用自己的webview加载

               return false;

           } else {            

              //跳转外部浏览器

              Intent intent = new Intent(Intent.ACTION_VIEW, uri);

              context.startActivity(intent);             

              return true;

           }

       }     return   super.shouldOverrideUrlLoading(view, url);

 }

注:如果使用的是Post请求方式,则此方法不会被回调

2、shouldOverrideUrlLoading(WebView   view, WebResourceRequest request)在API 24以后新加的,使用同上。

3、shouldInterceptRequest(WebView   view, String url)

在API 21以后过时,通知Application加载资源的请求并返回请求的资源,如果返回值是Null,Webview仍然会按正常加载资源;否则返回的数据将会被使用

注:回调发生在子线程中,不能直接进行UI操作

4、shouldInterceptRequest(WebView   view, WebResourceRequest request)

在API 21以后新加,使用同上

5、onPageStarted(WebView view,   String url, Bitmap favicon)通知Application页面已经开始加载资源,页面加载过程中,onPageStarted至多会被执行一次

6、onPageFinished(WebView view,   String url)  通知Application页面已经加载完毕

7、onReceivedError(WebView   view, int errorCode, String description, String failingUrl)

通知Application有错误发生,这些错误是不可恢复的(即主要的资源不可用)。errorCode参数对应于一个ERROR_ *常量

8、shouldOverrideKeyEvent(WebView view, KeyEvent event) 
//重写此方法才能够处理在浏览器中的按键事件。 
9、doUpdateVisitedHistory(WebView view, String url, boolean isReload)   
//(更新历史记录) 
10、onLoadResource(WebView view, String url)  
// 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。 

3.4    WebCromeClient方法详解

1、onProgressChanged(WebView   view, int newProgress)

通知Application的加载进度,newProgress取值范围[0,100],可以通过这个方法来编写一个带加载进度条的Webview

2、onReceivedTitle(WebView   view, String title)

    当加载页面标题有改变时会通知Application,title即为新标题。

4       Android studio中打包MUI项目

1.    使用HBuilder创建一个web app的项目,如下图:

Android混合开发详解-LMLPHP

 

2.    在Android studio中新建一个项目

3.    去官网下载对应的html5+sdk


4.    将HBuilder项目拷贝到Android studio中的assets文件夹中

Android混合开发详解-LMLPHP

 

Android混合开发详解-LMLPHP

5.    接下来需要将打包所用到的jar包和配置文件从下载的5+SDK中拷贝到Android studio里面

注意:jar包拷贝到libs文件夹下面,在 assets目录下新建一个data文件夹,并将对应的配置文件拷贝过去,更改配置文件中的appid;

从下载的5+SDK中的sdk文件夹下的libs中拷贝相应的jar包到Android studio中

Android混合开发详解-LMLPHP

将5+sdk包中的HBuidler-Integrate下assetsàdata目录中的配置文件全部包拷贝到studio中assets目录下的data目录中更改一下文件名,如下图所示.

 

Android混合开发详解-LMLPHP

修改control.xml中的appid与hbuilder中的一致

Android混合开发详解-LMLPHP

将5+sdk下面HBuidler-Integrate-àres下的所有文件拷贝到studio中的res文件夹下,主要是mui项目转换为Android项目后的一些资源文件;

Android混合开发详解-LMLPHP

拷贝HBuidler-Integrate-à src\com\HBuilder\integrate目录下的SDK_WebApp到对应的studio项目的包下面作为项目的入口Activity,这个时候还需要拷贝HBuilder-Integrate\src下的io包到studio的java目录下,如图所示:

Android混合开发详解-LMLPHP

修改AndroidMnifest.xml配置文件的入口Activity和相应的权限

xml version="1.0" encoding="utf-8"?>
   <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.zwj.muiorandroid">
  
     <application
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
         android:supportsRtl="true"
         android:theme="@style/AppTheme">
         <activity android:name=".SDK_WebApp">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
  
                 <category android:name="android.intent.category.LAUNCHER"/>
             intent-filter>
         activity>
     application>
  
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.GET_TASKS" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  
 manifest>
 

 

运行程序即可,现在就已经把HBuilder的项目转换为原生的Android项目打包结构

 


10-29 14:02