简单网页浏览器的实现
这几天学习了Android关于网页访问及浏览器实现方面的知识,今天简单总结一下。
Android中提供了一个组件——WebView,使得浏览器的实现变得非常简单,当然这里指的是比较初级的。
下面先贴上代码吧。
1、布局文件
布局文件为avtivity_main.xml,由一个网址输入框AutoCompleteTextView、一个网页播放页WebView及三个按钮组成(完成的功能分别为上一页、下一页及刷新)
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" > 5 6 <AutoCompleteTextView 7 android:id="@+id/url" 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:hint="@string/url" 11 android:inputType="textUri" 12 android:completionHint="@string/url" 13 android:completionThreshold="1" /> 14 15 <WebView 16 android:id="@+id/show" 17 android:layout_width="match_parent" 18 android:layout_height="match_parent" 19 android:layout_above="@+id/btnLayout" 20 android:layout_below="@+id/url" /> 21 22 <LinearLayout 23 android:id="@+id/btnLayout" 24 android:layout_width="match_parent" 25 android:layout_height="wrap_content" 26 android:layout_alignParentBottom="true" 27 android:layout_alignParentLeft="true" 28 android:layout_alignParentRight="true" 29 android:orientation="horizontal" > 30 31 <Button 32 android:id="@+id/back" 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 android:layout_weight="1.0" 36 android:text="@string/back" /> 37 38 <Button 39 android:id="@+id/forward" 40 android:layout_width="wrap_content" 41 android:layout_height="wrap_content" 42 android:layout_weight="1.0" 43 android:text="@string/forward" /> 44 45 <Button 46 android:id="@+id/refresh" 47 android:layout_width="wrap_content" 48 android:layout_height="wrap_content" 49 android:layout_weight="1.0" 50 android:text="@string/refresh" /> 51 52 </LinearLayout> 53 54 </RelativeLayout>
2、字串定义
组件中所需要的文本字串定义在文件strings.xml,定义了上述四个组件(不包括WebView)的显示文本
1 <resources> 2 3 <string name="app_name">WebView</string> 4 5 <string name="hello_world">Hello world!</string> 6 <string name="action_settings">Settings</string> 7 8 <string name="url">请输入网址</string> 9 <string name="back">上一页</string> 10 <string name="forward">下一页</string> 11 <string name="refresh">刷新</string> 12 13 </resources>
3、java实现
主文件MainActivity.java,实现了各个组件所应该完成的功能
1 package com.xxx.webview; 2 3 import java.util.Timer; 4 5 import java.util.Timer; 6 import java.util.TimerTask; 7 import java.util.regex.Matcher; 8 import java.util.regex.Pattern; 9 10 import android.app.Activity; 11 import android.graphics.Bitmap; 12 import android.os.Bundle; 13 import android.os.Handler; 14 import android.os.Message; 15 import android.view.KeyEvent; 16 import android.view.Menu; 17 import android.view.View; 18 import android.view.View.OnClickListener; 19 import android.webkit.WebView; 20 import android.webkit.WebViewClient; 21 import android.widget.ArrayAdapter; 22 import android.widget.AutoCompleteTextView; 23 import android.widget.Button; 24 import android.widget.Toast; 25 26 public class MainActivity extends Activity { 27 28 AutoCompleteTextView url; 29 WebView show; 30 31 String[] urlArray = new String[] 32 { 33 "www.baidu.com", "www.bing.com" 34 }; 35 36 @Override 37 public void onCreate(Bundle savedInstanceState) { 38 super.onCreate(savedInstanceState); 39 setContentView(R.layout.activity_main); 40 41 final Activity activity = this; 42 43 show = (WebView)findViewById(R.id.show); 44 show.getSettings().setJavaScriptEnabled(true); 45 show.getSettings().setBuiltInZoomControls(true); 46 show.setWebViewClient(new WebViewClient() { 47 public boolean shouldOverrideUrlLoading(WebView view, String strUrl) { 48 view.loadUrl(strUrl); 49 url.setText(strUrl); 50 return false; 51 } 52 53 public void onPageStarted(WebView view, String strUrl, Bitmap favicon) { 54 super.onPageStarted(view, strUrl, favicon); 55 url.setText(strUrl); 56 } 57 58 public void onPageFinished(WebView view, String strUrl) { 59 } 60 61 public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { 62 Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show(); 63 } 64 }); 65 66 67 url = (AutoCompleteTextView)findViewById(R.id.url); 68 ArrayAdapter<String> urlAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, urlArray); 69 url.setAdapter(urlAdapter); 70 url.setOnKeyListener(new View.OnKeyListener() 71 { 72 public boolean onKey(View v, int keyCode, KeyEvent ev) 73 { 74 if (keyCode == KeyEvent.KEYCODE_ENTER) 75 { 76 String strUrl = url.getText().toString(); 77 78 Pattern p = Pattern.compile("http://([\\w-]+\\.)+[\\w-]+(/[\\w-\\./?%=]*)?"); 79 Matcher m = p.matcher(strUrl); 80 if (!m.find()) 81 { 82 strUrl = "http://" + strUrl; 83 } 84 85 show.loadUrl(strUrl); 86 87 return true; 88 } 89 90 return false; 91 } 92 }); 93 94 // button 95 final Button backBtn = (Button)findViewById(R.id.back); 96 final Button forwardBtn = (Button)findViewById(R.id.forward); 97 Button refreshBtn = (Button)findViewById(R.id.refresh); 98 backBtn.setEnabled(false); 99 forwardBtn.setEnabled(false); 100 101 backBtn.setOnClickListener(new OnClickListener() 102 { 103 public void onClick(View v) 104 { 105 show.goBack(); 106 } 107 }); 108 109 forwardBtn.setOnClickListener(new OnClickListener() 110 { 111 public void onClick(View v) 112 { 113 // TODO 114 show.goForward(); 115 } 116 }); 117 118 refreshBtn.setOnClickListener(new OnClickListener() 119 { 120 public void onClick(View v) 121 { 122 // TODO 123 String strUrl = url.getText().toString(); 124 show.loadUrl(strUrl); 125 } 126 }); 127 128 final Handler handler = new Handler() 129 { 130 @Override 131 public void handleMessage(Message msg) 132 { 133 if (msg.what == 0x1111) 134 { 135 // whether can go back 136 if (show.canGoBack()) 137 { 138 backBtn.setEnabled(true); 139 } 140 else 141 { 142 backBtn.setEnabled(false); 143 } 144 145 // whether can go forward 146 if (show.canGoForward()) 147 { 148 forwardBtn.setEnabled(true); 149 } 150 else 151 { 152 forwardBtn.setEnabled(false); 153 } 154 } 155 156 super.handleMessage(msg); 157 } 158 }; 159 160 // create thread to change button states 161 new Timer().schedule(new TimerTask() 162 { 163 public void run() 164 { 165 Message msg = new Message(); 166 msg.what = 0x1111; 167 handler.sendMessage(msg); 168 } 169 }, 0, 100); 170 } 171 172 @Override 173 public boolean onKeyDown(int keyCode, KeyEvent event) { 174 175 if ((keyCode == KeyEvent.KEYCODE_BACK) && show.canGoBack()) 176 { 177 show.goBack(); 178 return true; 179 } 180 181 return super.onKeyDown(keyCode, event); 182 } 183 184 }
4、权限添加
千万不能少了网页访问等操作所需要的权限,在AndroidManifest.xml文件中加入以下代码
1 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" ></uses-permission> 2 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" ></uses-permission> 3 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses-permission> 4 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" ></uses-permission> 5 <uses-permission android:name="android.permission.INTERNET" ></uses-permission> 6 <uses-permission android:name="android.permission.WAKE_LOCK" ></uses-permission>
当然仅仅对于网页访问来说,上面列出的几个不都是必须的,这里主要是为以后进一步的功能实现做准备。
5、代码分析
这里,主要介绍一下主文件MainActivity.java中几个值得注意并且比较有用的知识点。
a) 定义了一个网址数组urlArray,利用它的值生成一个ArrayAdapter赋给了AutoCompleteTextView,然后为网址编辑框添加OnKeyListener,并设置了匹配及自动弹出匹配结果的响应代码;代码从68行开始;
b) 定义了一个定时、消息发送与处理模块,使得程序每个0.1秒检查一次当前网页浏览情况,响应地对上一页及下一页的按钮状态进行改变;代码从128行开始;
其他的代码实现都是一些常规的,就不一一描述了。
6、结果图
初始界面:
输入网址:
网页访问: