安卓对HTML的处理

一、安卓中网页基础


1、调用系统浏览器访问:
Button bt1 = (Button) findViewById(R.id.open_url);
bt1.setOnClickListener(new OnClickListener() {
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		Uri uri = Uri.parse("http://translate.google.cn/");
		Intent intent = new Intent(Intent.ACTION_VIEW, uri);
		startActivity(intent);
	}
});


Uri.parse()方法返回的是一个URI类型,通过这个URI可以访问一个网络上的或者本地的资源,Intent()方法告诉系统调用哪个组件来带开这个URI。这里指明的是使用Intent.ACTION_VIEW,这将调用系统里面的浏览器来打开指定的网页。




2、通过WebView在应用内部打开:
在应用内部打开网页可以使用WebView控件。WebView是Android里面的浏览器组件,负责打开HTML文件。
setContent()方法动态的添加布局。
loadUrl()方法从网址加载一个网页。
loadData()和loadDataWithBaseURL()方法都是从字符串来加载一个页面。


WebView打开网页的方法如下:
WebView webView=(WebView) findViewById(R.id.webView);
webView.loadUrl("http://www.baidu.com/");


loadUrl的原型如下:
void loadData(String data,String mimeType,String encoding)
其各参数含义如下:
data:数据字符串。
mimeType:表明数据的MIME类型,如text/html。
encoding:数据的编码,如果参数encoding的值为base64,则必须使用base64编码之后的数据。


loadUrl方法在遇到错误网页的时候不会报出异常。
loadData方法不能处理js、https等格式的页面特效。如果需要检测页面异常,可以先对页面进行判定。
loadDataWithBaseURL()可以加载https等特殊页面。


在AndroidManifest配置页面中需要添加网络权限:
<uses-permission 
        android:name="android.permission.INTERNET"/>


如果点击WebView的一个链接,显示结果时,已经超出应用的范围了,如果希望页面数据可以显示在应用内部,可以使用WebView的setWebViewClient()方法来解决这个问题。


Button bt_openUrl=(Button) findViewById(R.id.bt_openUrl);
webView=(WebView) findViewById(R.id.webView);        
bt_openUrl.setOnClickListener(new OnClickListener() {			
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		webView.loadUrl("http://translate.google.cn/m");
//		webView.setWebViewClient(new WebViewClient(){
//			@Override
//			public boolean shouldOverrideUrlLoading(WebView view,
//				String url) {
//				// TODO Auto-generated method stub
//				view.loadUrl(url);
//				return true;
//			}					
//		});
	}
});





3、网页下载
bt_openUrl.setOnClickListener(new OnClickListener() {			
	@Override
	public void onClick(View v) {
		try {
			URL newUrl=new URL("http://www.baidu.com/");
			URLConnection connect=newUrl.openConnection();
			DataInputStream dis=new DataInputStream(connect.getInputStream());
			BufferedReader in=new BufferedReader(new InputStreamReader(dis,"UTF-8"));
			//BufferedReader in = new BufferedReader(
				new InputStreamReader(connect.getInputStream(),"UTF-8"));
			String html="";
			String readLine=null;
			while ((readLine=in.readLine())!=null) {
			html=html+readLine;
			System.out.println(readLine);						
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
});   


为了保存用户搜索的页面,首先需要通过网址生成URL对象,然后打开链接,写入Buffer中,最后写入字符串中,为了方便进一步的处理。






二、Android WebView使用基础
   
1、WebView基本使用
WebView是View的一个子类,可以让你在activity中显示网页。
可以在布局文件中写入WebView:比如下面这个写了一个填满整个屏幕的WebView: 

<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/webview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>




加载一个网页,使用loadUrl():
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.example.com");




注意要在manifest中加上访问网络的权限:
<manifest ... > 
    <uses-permission android:name="android.permission.INTERNET" /> 
    ... 
</manifest>
 


2、设置WebView要显示的网页
设置WevView要显示的网页方法有很多:
(1)互联网页面直接用: 
myWebView.loadUrl(“http://www.google.com“);


(2)本地文件用:
myWebView.loadUrl(“file:///android_asset/XX.html“);  
本地文件存放在:assets文件中。


(3)还可以直接载入html的字符串,如:
String htmlString = "<h1>Title</h1><p>This is HTML text<br /><i>Formatted in italics</i><br />Anothor Line</p>";
// 载入这个html页面
myWebView.loadData(htmlString, "text/html", "utf-8");
 


3、在WebView中使用JavaScript
如果你想要载入的页面中用了JavaScript,你必须为你的WebView使能JavaScript。
一旦能使用之后,你也可以自己创建接口在你的应用和JavaScript代码间进行交互。
可以通过getSettings()获得WebSettings,然后用setJavaScriptEnabled()使能使用JavaScript:
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);






4、处理页面浏览
当用户点击了你的WebView中的一个链接,默认的行为是Android启动一个处理URL的应用,通常,默认的浏览器打开并下载目标URL。
但是,你可以在你的WebView中覆盖这一行为,使得连接仍在你的WebView中打开。
之后,根据在WebView中维护的网页浏览历史,你可以允许用户向前或向后浏览他们的网页。
(1)在WebView中打开所有链接
要打开用户点击的链接,只需要用setWebViewClient()方法向你的WebView提供一个WebViewClient 比如:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.example.com/");
//myWebView.setWebViewClient(new WebViewClient());
myWebView.setWebViewClient(new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
     view.loadUrl(url);
	  return true;
        }
});


此时就OK了, 就可以在你的WebView中打开链接了。


(2)注意:
大部分网址,比如:http://translate.google.cn/m,有了WebView,第一次打开就能在WebView中,但是有一些网址比如:http://www.baidu.com/,有了WebView,第一次打开却在默认浏览器中。但是不论哪一种,如果调用了setWebViewClient()函数所有的网页就会都在WebView中显示。


(3)关于打开链接位置的更多控制
如果你对在哪里打开链接需要更多的控制,你可以创建自己的类,继承 WebViewClient,然后覆写shouldOverrideUrlLoading()方法。
比如下面这个:
    
private class MyWebViewClient extends WebViewClient
    {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
       if(Uri.parse(url).getHost().equals("http://www.example.com/"))
            {
                // This is my web site, so do not override; let my WebView load
                // the page
                return false;
            }
            // Otherwise, the link is not for a page on my site, so launch
            // another Activity that handles URLs
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(intent);
            return true;
        }
    }


将特定的链接用自己的WebView打开,其他链接用浏览器(intent启动了默认的处理URL的Activity)。
定义完之后把这个类的对象传入setWebViewClient()方法即可。 
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new MyWebViewClient());




(4)浏览网页历史回退
当你的WebView覆写了URL载入的行为,它会自动地对访问过的网页积累一个历史,你可以利用 goBack() 和 goForward()方法在这个历史中前进或后退。
比如说使用后退键进行网页后退:
   
 /**
     * 按键响应,在WebView中查看网页时,按返回键的时候按浏览历史退回,如果不做此项处理则整个WebView返回退出
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        // Check if the key event was the Back button and if there's history
        if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack())
        {
            // 返回键退回
            myWebView.goBack();
            return true;
        }
        // If it wasn't the Back key or there's no web page history, bubble up
        // to the default
        // system behavior (probably exit the activity)
        return super.onKeyDown(keyCode, event);
    }


canGoBack() 方法在网页可以后退时返回true。
类似的,canGoForward()方法可以检查是否有可以前进的历史记录。
如果你不执行这种检查,一旦 goBack() 和 goForward()方法到达历史记录顶端,它们将什么也不做。
如果不加这种设置,在用户按下Back键时,如果是WebView显示网页,则会将WebView作为整体返回。




5、程序实例
附上完整的程序:
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;


@SuppressLint("SetJavaScriptEnabled")
public class WebActivity extends Activity
{
    private WebView myWebView = null;


    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);


        // 打开网页
        myWebView = (WebView) findViewById(R.id.webview);
        //


        // myWebView.loadUrl("http://www.cnblogs.com/mengdd/");// 博客链接
        myWebView.loadUrl("http://www.baidu.com/");// 百度链接


        // JavaScript使能(如果要加载的页面中有JS代码,则必须使能JS)
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);


        // 在WebView中打开链接(默认行为是使用浏览器,设置此项后都用WebView打开)
        // myWebView.setWebViewClient(new WebViewClient());
        // 这样设置后所有的链接都会在当前WebView中打开


        // 更强的打开链接控制:自己覆写一个WebViewClient类:除了指定链接从WebView打开,其他的链接默认打开
        myWebView.setWebViewClient(new MyWebViewClient());


    }


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


    /**
     * 自定义的WebViewClient类,将特殊链接从WebView打开,其他链接仍然用默认浏览器打开
     * 
     * @author 1
     * 
     */
    private class MyWebViewClient extends WebViewClient
    {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            if (Uri.parse(url)
                    .getHost()
                    .equals("http://www.cnblogs.com/mengdd/archive/2013/02/27/2935811.html")
                    || Uri.parse(url).getHost()
                            .equals("http://music.baidu.com/"))
            {
                // This is my web site, so do not override; let my WebView load
                // the page


                // 这是官网上的例子,但是我点击特定链接的时候仍然是用浏览器而不是用自己的WebView打开,加上下面这句view.loadUrl(url)仍然是用浏览器,无解,不知道哪里出了问题
                // view.loadUrl(url);
                return false;
            }
            // Otherwise, the link is not for a page on my site, so launch
            // another Activity that handles URLs
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(intent);
            return true;
        }
    }


    /**
     * 按键响应,在WebView中查看网页时,按返回键的时候按浏览历史退回,如果不做此项处理则整个WebView返回退出
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        // Check if the key event was the Back button and if there's history
        if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack())
        {
            // 返回键退回
            myWebView.goBack();
            return true;
        }
        // If it wasn't the Back key or there's no web page history, bubble up
        // to the default
        // system behavior (probably exit the activity)
        return super.onKeyDown(keyCode, event);
    }


}






三、安卓WebView总结


浏览器控件是每个开发环境都具备的,这为马甲神功提供了用武之地,windows的有webbrowser,android和ios都有webview。只是其引擎不同,相对于微软的webbrowser,android及ios的webview的引擎都是webkit,对Html5提供支持。本篇主要介绍android的webview之强大。
A.    webview组件如何使用
 
1)       添加权限:AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错误。
2)       在要Activity中生成一个WebView组件:WebView webView = new WebView(this);或者可以在activity的layout文件里添加webview控件:
<WebView
android:id="@+id/wv"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="@string/hello"
    />


3)       设置WebView基本信息:
          如果访问的页面中有Javascript,则webview必须设置支持Javascript。
          webview.getSettings().setJavaScriptEnabled(true);  
          触摸焦点起作用
          requestFocus();
          取消滚动条
          this.setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY);
 
4)       设置WevView要显示的网页:
          互联网用:webView.loadUrl("http://www.google.com"); 
          本地文件用:webView.loadUrl("file:///android_asset/XX.html");  本地文件存放在:assets文件中
5)       如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。给WebView添加一个事件监听对象(WebViewClient)并重写其中的一些方法:
 shouldOverrideUrlLoading:对网页中超链接按钮的响应。当按下某个连接时WebViewClient会调用这个方法,并传递参数:按下的url。比如当webview内嵌网页的某个数字被点击时,它会自动认为这是一个电话请求,会传递url:tel:123,如果你不希望如此可通过重写shouldOverrideUrlLoading函数解决:
  
public boolean shouldOverrideUrlLoading(WebView view,String url){  
  
        if(url.indexOf("tel:")<0){//页面上有数字会导致连接电话  
  
            view.loadUrl(url);  
  
        }  
  
           return true;            
  
       }  





        另外还有其他一些可重写的方法 
1,接收到Http请求的事件
onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) 
2,打开链接前的事件
public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } 
这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。
 
3,载入页面完成的事件
public void onPageFinished(WebView view, String url){ } 
同样道理,我们知道一个页面载入完成,于是我们可以关闭loading条,切换程序动作。
 
4,载入页面开始的事件
public void onPageStarted(WebView view, String url, Bitmap favicon) { } 
这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。
 
通过这几个事件,我们可以很轻松的控制程序操作,一边用着浏览器显示内容,一边监控着用户操作实现我们需要的各种显示方式,同时可以防止用户产生误操作。
      
6)       如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消费掉该Back事件。
       覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。
  
public boolean onKeyDown(int keyCoder,KeyEvent event){  
                        if(webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){  
                                 webview.goBack();   //goBack()表示返回webView的上一页面  
  
                                return true;  
                         }  
                         return false;  
                }  






B.    Webview与js交互
Webview与js的双向交互才是android的webview强大所在,也是马甲精神能够彻底执行的基础保障。


//activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.webviewdemo.MainActivity"
    android:orientation="vertical" >


    <Button 
        android:id="@+id/bt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="点击"
        android:onClick="btnClick"/>
    
    <WebView 
        android:id="@+id/wv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


</LinearLayout>








//MainActivity.java
public class MainActivity extends Activity {
	WebView wv;
   
    @SuppressLint({  "SetJavaScriptEnabled", "JavascriptInterface" }) 
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        wv=(WebView) findViewById(R.id.wv);
        WebSettings webSettings = wv.getSettings();
        webSettings.setJavaScriptEnabled(true);
      //让WebView加载本地html文件  
        wv.loadUrl("file:///android_asset/demo.html");  
        wv.setWebChromeClient(new WebChromeClient());  
        //设置WebView的js接口,通过此处的设置,让js可以调用Java代码  
        wv.addJavascriptInterface(MainActivity.this, "client");  
       
    }
    
  //这是Activity中显示的按钮的点击事件,测试通过Java调用js方法  
    public void btnClick(View view){  
    	wv.loadUrl("javascript:test()");  
    }  


    //这是将会被js调用的Java方法,当html文件中的按钮被点击时执行该方法 
    //安卓API达到17需要加上 @JavascriptInterface
    @JavascriptInterface
    public void showToast(){  
        Toast.makeText(MainActivity.this, "this function is called by js", Toast.LENGTH_SHORT).show();  
    }  
}




//demo.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>title</title>
</head>
<body>
<script language='javascript'>


<!-- 该方法是被Java代码调用的 -->
function test(){
	alert('my name is yubo');
}


<!-- 该方法最后将调用Java代码中的showToast()方法 -->
function btnclick(){	
	client.showToast();
}


</script>


<!-- html显示文本 -->
hello, world!


<br/>


<!-- html显示按钮 -->
<input type="button" value="show toast" οnclick="btnclick()"/>
</body>
</html>



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