WebView
简介
- 一般用于加载一些网络界面
- Android内置webkit内核的高性能浏览器,而WebView则是在这个基础上进行封装后的一个 控件,WebView直译网页视图,我们可以简单的看作一个可以嵌套到界面上的一个浏览器控件!
方法
- WebChromeClient
辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
方法 | 作用 |
onJsAlert(WebView view,String url,String message,JsResult result) | 处理Js中的Alert对话框 |
onJsConfirm(WebView view,String url,String message,JsResult result) | 处理Js中的Confirm对话框 |
onJsPrompt(WebView view,String url,String message,String defaultValue,JsPromptResult result) | 处理Js中的Prompt对话框 |
onProgressChanged(WebView view,int newProgress) | 当加载进度条发生改变时调用 |
onReceivedIcon(WebView view, Bitmap icon) | 获得网页的icon |
onReceivedTitle(WebView view, String title) | 获得网页的标题 |
- WebViewClient
辅助WebView处理各种通知与请求事件
方法 | 作用 |
onPageStared(WebView view,String url) | 通知主程序网页开始加载 |
onPageFinished(WebView view,String url,Bitmap favicon) | 通知主程序,网页加载完毕 |
doUpdateVisitedHistory(WebView view,String url,boolean isReload) | 更新历史记录 |
onLoadResource(WebView view,String url) | 通知主程序WebView即将加载指定url的资源 |
onScaleChanged(WebView view,float oldScale,float newScale) | ViewView的缩放发生改变时调用 |
shouldOverrideKeyEvent(WebView view,KeyEvent event) | 控制webView是否处理按键时间,如果返回true,则WebView不处理,返回false则处理 |
shouldOverrideUrlLoading(WebView view,String url) | 控制对新加载的Url的处理,返回true,说明主程序处理WebView不做处理,返回false意味着WebView会对其进行处理 |
onReceivedError(WebView view,int errorCode,String description,String failingUrl) | 遇到不可恢复的错误信息时调用 |
- WebSettings
WebView相关配置的设置,比如setJavaScriptEnabled()设置是否允许JS脚本执行
方法 | 作用 |
getSettings() | 返回一个WebSettings对象,用来控制WebView的属性设置 |
loadUrl(String url) | 加载指定的Url |
loadData(String data,String mimeType,String encoding) | 加载指定的Data到WebView中.使用"data:"作为标记头,该方法不能加载网络数据.其中mimeType为数据类型如:textml,image/jpeg. encoding为字符的编码方式 |
loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) | 比上面的loadData更加强大 |
setWebViewClient(WebViewClient client) | 为WebView指定一个WebViewClient对象.WebViewClient可以辅助WebView处理各种通知,请求等事件。 |
setWebChromeClient(WebChromeClient client) | 为WebView指定一个WebChromeClient对象,WebChromeClient专门用来辅助WebView处理js的对话框,网站title,网站图标,加载进度条等 |
实例
- xml
<WebView
android:id="@+id/web_view"
android:layout_width="409dp"
android:layout_height="729dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("https://www.baidu.com");
}
}
- Manifest
在Android9.0之后,url不支持明文格式,所以要么进行加密https,要么在application里添加一行android:usesCleartextTraffic="true"(但是也不行),或者降低SDK版本
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:usesCleartextTraffic="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>
- 下载地址
DoSomeAndroidTest/WebView at main · qricis/DoSomeAndroidTest · GitHub
网络请求方式
- 在过去,Android上发送Http请求一般有两种方式:HttpURLConnection和HttpClient,但是由于HttpClient的API数量过多,在Android6.0的系统中,被完全移除了
// HttpURLConnection
// 获取该实例
URL url = new URL("http://baidu.com");
HttpUriConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求所用的方法(get/post),get表示希望从服务器获取数据,post表示希望提交数据给服务器
connection.setRequestMethod("GET")
// 连接超时
connection.setConnectTimeout(8000);
// 读取超时的毫秒数
connection.setReadTimeout(8000);
// 获取服务器返回的输入流
InputStream in = connection.getInputStream();
// 调用disconnect()方法关闭该http连接
connection.disconnect()
- xml
<Button
android:id="@+id/send_request"
android:layout_width="163dp"
android:layout_height="0dp"
android:text="@string/sendrequest"
android:onClick="sendResquest"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.08"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="1dp"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.9"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/send_request"
app:layout_constraintVertical_bias="1.0">
<TextView
android:id="@+id/response_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
- Manifest
<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>
- MainActivity
public class MainActivity extends AppCompatActivity {
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
responseText = findViewById(R.id.response_text);
}
public void sendResquest(View view) {
sendRequestWithHttpURLConnection();
}
private void sendRequestWithHttpURLConnection() {
//开启线程来发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL("https://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
//向服务器提交数据的写法
/*connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");*/
//对获取到的输入流进行读取
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
showResponse(response.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
private void showResponse(final String response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//在这里进行UI操作,将结果显示在界面上
responseText.setText(response);
}
});
}
}
OkHttp
- build.gradle
implementation 'com.squareup.okhttp3:mockwebserver:4.8.1'
- MainActivity
private void sendRequestWithOkHttp() {
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.baidu.com")
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
showResponse(responseData);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
- 升级版(解析数据)
private void parseXMLWithPull(String xmlData) {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlData));
int eventType = xmlPullParser.getEventType();
String id = "";
String name = "";
String version = "";
while (eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = xmlPullParser.getName();
switch (eventType) {
//开始解析某个节点
case XmlPullParser.START_TAG:{
if ("id".equals(nodeName)) {
id = xmlPullParser.nextText();
} else if ("name".equals(nodeName)) {
name = xmlPullParser.nextText();
} else if ("version".equals(nodeName)) {
version = xmlPullParser.nextText();
}
break;
}
//完成解析某个节点
case XmlPullParser.END_TAG:{
if ("app".equals(nodeName)) {
Log.d("MainActivity","id is " + id);
Log.d("MainActivity","name is " + name);
Log.d("MainActivity","version is " + version);
}
break;
}
default:
break;
}
eventType = xmlPullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void parseXMLWithSAX(String xmlData) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
ContentHandler handler = new ContentHandler();
//将ContentHandler的实例设置到XMLReader中
xmlReader.setContentHandler(handler);
//开始执行解析
xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
}
}
private void parseJSONWithJSONObject(String jsonData) {
try {
JSONArray jsonArray = new JSONArray(jsonData);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String version = jsonObject.getString("version");
Log.d("MainActivity","id is " + id);
Log.d("MainActivity","name is " + name);
Log.d("MainActivity","version is " + version);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void parseJSONWithGson(String jsonData) {
Gson gson = new Gson();
List<App> appList = gson.fromJson(jsonData,new TypeToken<List<App>>(){}.getType());
for (App app : appList) {
Log.d("MainActivity","id is " + app.getId());
Log.d("MainActivity","name is " + app.getName());
Log.d("MainActivity","version is " + app.getVersion());
}
}
private void showResponse(final String response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//在这里进行UI操作,将结果显示在界面上
responseText.setText(response);
}
});
}
下载地址
DoSomeAndroidTest/NetworkTest at main · qricis/DoSomeAndroidTest · GitHub