前一段時間看了一下WebView的內容,自己試着寫了幾個小的程序。現在進行一下個人的小結,爲了以後自己忘記的時候還可以看看。
在Android系統中內嵌了一個高性能的webkit內核瀏覽器,在SDK中封裝爲一個叫做WebView組件,通過這個組件可以像瀏覽器一樣地去解析網頁。使用的時候可以直接加載網址進行瀏覽。
那麼什麼是webkit?官方的解釋是:WebKit是Mac OS X v10.3及以上版本所包含的軟件框架(對v10.2.7及以上版本也可通過軟件更新獲取)。 同時,WebKit也是Mac OS X的Safari網頁瀏覽器的基礎。WebKit是一個開源項目,主要由KDE的KHTML修改而來並且包含了一些來自蘋果公司的一些組件。 傳統上,WebKit包含一個網頁引擎WebCore和一個腳本引擎JavaScriptCore,它們分別對應的是KDE的KHTML和KJS。不過, 隨着JavaScript引擎的獨立性越來越強,現在WebKit和WebCore已經基本上混用不分(例如Google Chrome和Maxthon 3採用V8引擎,卻仍然宣稱自己是WebKit內核)。
不理解這些也不耽誤我們去使用的,這裏就以一個自己寫的小程序來說一下。這裏先看一下完成之後的截圖(做的不好,主要是爲了講解)
第一個是打開後的第一個頁面,是要輸入網址的,第二個是輸入的網址,第三個是加載之後的頁面。
下面是代碼的介紹
- 佈局文件
這個程序有兩個Activity,第一個輸入網址的是第一個Activity,第二個Activity是含有WebView組件的用來加載網頁的(第三個圖片),下面是第一個Activity的佈局文件,文件名是startactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableRow>
<EditText
android:id="@+id/edittext"
android:layout_weight="0.7"
android:text="輸入網址" />
<Button
android:layout_weight="0.3"
android:text="Load"
android:id="@+id/btn"
/>
</TableRow>
<TableRow>
<TableLayout>
<TableRow>
<Button
android:text="http://"
android:layout_weight="0.25"
android:id="@+id/http"
/>
<Button
android:text="www."
android:layout_weight="0.25"
android:id="@+id/www"
/>
<Button
android:text=".com"
android:layout_weight="0.25"
android:id="@+id/com"
/>
<Button
android:text="清空"
android:layout_weight="0.25"
android:id="@+id/clear"
/>
</TableRow>
</TableLayout>
</TableRow>
</TableLayout>
第二個Activity的佈局文件,文件名activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<WebView
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
第三個是AndroidMainifset文件,這個有一個要注意的地方,要給添加了WebView之間的Activity添加訪問網絡的權限,在第9行
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.webview"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.webview.MainActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.example.webview.StartActivity"
android:label="@string/start_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
第一個比較簡單,我們直接看第二個,WebView的使用方式和其他的控件類似,它的一些常用屬性如下
setAllowFileAccess 啓用或禁止WebView訪問文件數據
setBlockNetworkImage 是否顯示網絡圖像
setBuiltInZoomControls 設置是否支持縮放
setCacheMode 設置緩衝的模式
setDefaultFontSize 設置默認的字體大小
setDefaultTextEncodingName 設置在解碼時使用的默認編碼
setFixedFontFamily 設置固定使用的字體
setJavaSciptEnabled 設置是否支持Javascript
setLayoutAlgorithm 設置佈局方式
setLightTouchEnabled 設置用鼠標激活被選項
setSupportZoom 設置是否支持變焦
WebViewClient常用方法:
doUpdate VisitedHistory 更新歷史記錄
onFormResubmission 應用程序重新請求網頁數據
onLoadResource 加載指定地址提供的資源
onPageFinished 網頁加載完畢
onPageStarted 網頁開始加載
onReceivedError 報告錯誤信息
onScaleChanged WebView發生改變
shouldOverrideUrlLoading 控制新的連接在當前WebView中打開
WebChromeClient常用方法:
onCloseWindow 關閉WebView
onCreateWindow 創建WebView
onJsAlert 處理Javascript中的Alert對話框
onJsConfirm處理Javascript中的Confirm對話框
onJsPrompt處理Javascript中的Prompt對話框
onProgressChanged 加載進度條改變
onReceivedlcon 網頁圖標更改
onReceivedTitle 網頁Title更改
onRequestFocus WebView顯示焦點
這個具體的使用大家可以百度,這些的用法是前端的要考慮的,我們這裏只是講解用法。
- 主程序代碼
第一個是startactivity的代碼,文件名 StartActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class StartActivity extends Activity implements OnClickListener
{
private EditText editText;
private Button button,button2,button3,button4,button5;
String webadress;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.startactivity);
editText=(EditText)findViewById(R.id.edittext);
button=(Button)findViewById(R.id.btn);
button2=(Button)findViewById(R.id.http);
button3=(Button)findViewById(R.id.www);
button4=(Button)findViewById(R.id.com);
button5=(Button)findViewById(R.id.clear);
button.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
button4.setOnClickListener(this);
button5.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn:
{
webadress=(String)editText.getText().toString();
Intent intent=new Intent();//新建一個意圖對象
intent.setClass(StartActivity.this, MainActivity.class);
//傳遞鍵值爲adress的字符串,在打開另一個的Activity中可以進行接收
intent.putExtra("adress", webadress);
startActivity(intent);
webadress=null;
break;
}
case R.id.http:
{//獲取光標位置
int index = editText.getSelectionStart();
//是一個公共的接口類型,可以變化,具體詳見introduce.txt文檔
Editable editable = editText.getText();
//在index位置進行添加內容
//editable.delete(index-1, index);刪除index位置前一個字符
editable.insert(index, "http://");
break;
}
case R.id.www:
{
int index = editText.getSelectionStart();
Editable editable = editText.getText();
editable.insert(index, "www.");
break;
}
case R.id.com:
{
int index = editText.getSelectionStart();
Editable editable = editText.getText();
editable.insert(index, ".com");
break;
}
case R.id.clear:
{
editText.setText("");
break;
}
default:
break;
}
}
}
第二個是MainActivity的代碼,文件名 MainActivity.java
import android.os.Bundle;
import android.R.string;
import android.app.Activity;
import android.content.Intent;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class MainActivity extends Activity {
private WebView webView;//聲明WebView對象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);//這個是設置WebView自帶的進度條,可以瞭解一下
setContentView(R.layout.activity_main);
//由於這個程序使用兩個Activity,這下面的一段是用來接收上一個Activity傳過來的網址的
Intent intent=getIntent();//新建Intent對象,用於上一個Activity數據的接收
Bundle bundle=intent.getExtras();
final String str=bundle.getString("adress");//得到鍵值爲adress的字符串
webView=(WebView)findViewById(R.id.webview);
//設置處理網頁中的JavaScript爲真
//當網頁中有js的時候可以進行簡單的處理
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSupportZoom(true);//支持縮放
webView.getSettings().setBuiltInZoomControls(true);//啓用內置縮放裝置
//這個WebViewClient是用來解析,渲染網頁的,具體的用法在之後的introduce.txt有說明
webView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
// TODO Auto-generated method stub
//Activity和WebView決定加載的進度條,加載到100%時,進度條消失
//該進度條是在標題欄的上方
setTitle(str);//設置標題欄的內容
setProgress(newProgress*100);
//當newprogress爲100的時候,停止
// super.onProgressChanged(view, newProgress);
}
});
//加載頁面,網址是str,這個是由上一個Activity傳過來的
webView.loadUrl(str);
webView.setWebViewClient(new MyWebViewClient());
}
//處理按鍵的響應,這個是用來返回上一個瀏覽的頁面的
@Override
public boolean onKeyDown(int keyCode,KeyEvent event)
{
if(keyCode==KeyEvent.KEYCODE_BACK)
{//調用cangoback函數來判斷是否有上一個網頁
if (webView.canGoBack())
{//調用goback函數,返回上一個網頁
webView.goBack();
return true;
}else finish();//如果已經是最後一個頁面的話,會退出程序
}
return false;
}
//自定義的視圖類, 當點擊鏈接時,希望是覆蓋當前而不是打開一個新的頁面,WebViewClient就是幫助WebView處理各種通知、請求事件的。具體解釋後面介紹
private class MyWebViewClient extends WebViewClient
{
//函數的重載,檢測網絡的連接
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "網絡連接失敗 ,請連接網絡。", Toast.LENGTH_SHORT).show();
super.onReceivedError(view, errorCode, description, failingUrl);
}
//這個是設置當點擊網頁上的鏈接時,是在這個頁面進行顯示,不會調用手機默認的瀏覽器進行加載,當不設置的時候,點擊會打開手機的默認瀏覽器
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
return true;
}
}
}
一些代碼的解釋在註釋中已經給出,下面是introduce.txt文檔
1.Editable
Editable 是一個接口類型,對它的實例化對象作出任何改變都是對原有的實例化對象操作的,內存地址還是原來的那個。
而對 String 的任何改變都是相當於重新實例化了一個 String 類出來,相當於重新分配了內存地址。
所以說 Editable 是可變的,String 是不可變的了;因爲 Editable 變了之後還是原來的 Editable 對象,
String 變了之後就已經不是原來的 String 對象了。
2.setWebChromeClient和setWebViewClient的區別
android.webkit庫聚合了webkit內核的瀏覽器功能,webview就是她的一個控件,可以使得網頁輕鬆的內嵌到app裏。
並且比較強大的是,還可以直接跟js相互調用。
webview有兩個方法:setWebChromeClient和setWebClient
setWebChromeClient主要處理解析,渲染網頁等瀏覽器做的事情
WebChromeClient是輔助WebView處理Javascript的對話框,網站圖標,網站title,加載進度等
onCloseWindow(關閉WebView)
onCreateWindow()
onJsAlert (WebView上alert是彈不出來東西的,需要定製你的WebChromeClient處理彈出)
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle
比如可以添加進度條,使得界面更友好
webview1.setWebChromeClient(new WebChromeClient()
{
public void onProgressChanged(WebView view, int progress)
{
setProgress(progress * 100);
if(progress == 100){
imageView1.setVisibility(View.GONE);
tv1.setVisibility(View.GONE);
pb1.setVisibility(View.GONE);
fy1.setVisibility(View.GONE);
}
}
}
);
WebViewClient就是幫助WebView處理各種通知、請求事件的,具體來說包括:
onLoadResource
onPageStart
onPageFinish
onReceiveError
onReceivedHttpAuthRequest
例如:
webview1.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{ // Handle the error
Toast.makeText(getApplicationContext(), "網絡連接失敗 ,請連接網絡。", Toast.LENGTH_SHORT).show();
}
public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); //設置字符集編碼
webview1.getSettings().setDefaultTextEncodingName("UTF-8");
webview1.loadUrl("http://www.android100.org/");
基本的介紹就是這些了,