网络编程
网络配置前置要求
进行任何网络编程前,必须在 AndroidManifest.xml 中配置权限和流量设置:
- 申请网络权限:
和<application>同级。
| <uses-permission android:name="android.permission.INTERNET" />
|
- Android 9.0 及以上版本默认禁止明文(HTTP)网络传输,若要支持 HTTP 请求,需在
<application> 标签中添加: | android:usesCleartextTraffic="true"
|
WebView 组件
用于在应用程序内部直接展示网页的控件。
- 基本加载:
| WebView webView = findViewById(R.id.webView);
webView.loadUrl("http://www.baidu.com");
|
- 允许执行 JavaScript(许多网页依赖 JS):
| webView.getSettings().setJavaScriptEnabled(true);
|
- 在当前 WebView 中打开链接(防止跳转到系统浏览器):
| webView.setWebViewClient(new WebViewClient());
|
Handler 异步通信
应用启动时默认开启一个主线程(UI线程)。
为了不阻塞UI线程的正常运行,我们需要将一些耗时操作(如联网下载文件)放在子线程中进行操作,操作完成后若需要更新UI,不能直接在子线程中进行(因为UI操作只能在UI线程中进行),所以需要通过Handler来进行UI线程和子线程间的通信。
子线程中无法修改主线程的内容,只能将值传递给主线程。
Handler常用方法
handleMessage(Message msg)在主类中重写,以实现接收到消息后的处理。
不需要显式调用,会自动触发。
sendMessage(Message msg)子线程中调用,发送消息对象msg。
Message类常用属性
- obj:Object类型,存放发送给消息接收者的任意类型的数据
HttpURLConnection
原生提供的网络请求 API,用于发送 HTTP 请求并获取响应。注意:网络请求属于耗时操作,必须在子线程(后台线程)中执行,否则会导致 ANR。
标准使用步骤:
| new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
// 1. 创建 URL 对象并打开连接
URL url = new URL("http://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
// 2. 设置请求方式和超时时间
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
// 3. 获取输入流并读取数据
InputStream in = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
// (处理 response 数据...)
} catch (Exception e) {
e.printStackTrace();
} finally {
// 4. 关闭流和连接
if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } }
if (connection != null) { connection.disconnect(); }
}
}
}).start();
|
线程与 UI 更新
Android 的 UI 是线程不安全的,不允许在子线程中直接修改 UI 控件(例如 TextView.setText())。
必须借助 runOnUiThread() 方法将更新 UI 的操作切换回主线程:
| runOnUiThread(new Runnable() {
@Override
public void run() {
// 在这里进行 UI 更新操作
textView.setText(responseData);
}
});
|
响应状态码
- 200:成功
- 403
- 404
- 500
- 502
- 503
OkHttp 网络库
OkHttp 是由 Square 公司开发的优秀第三方网络库,替代了原生繁琐的 API。
- 引入依赖: 在
build.gradle (app) 的 dependencies 中添加: | implementation 'com.squareup.okhttp3:okhttp:4.1.0'
|
GET 请求
| // 同样需要放在子线程中执行
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
// 同步执行请求
Response response = client.newCall(request).execute();
String responseData = response.body().string();
|
POST 请求
POST 请求需要先构建 RequestBody 来存放提交的数据:
| OkHttpClient client = new OkHttpClient();
// 构建请求体
RequestBody requestBody = new FormBody.Builder()
.add("username", "admin")
.add("password", "123456")
.build();
// 发送 POST 请求
Request request = new Request.Builder()
.url("http://www.example.com/login")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
|
JSON 解析 (GSON)
JSON 是一种轻量级的数据交换格式,GSON 是 Google 提供的开源解析库,可以方便地将 JSON 数据映射为 Java 对象。
- 引入依赖:
| implementation 'com.google.code.gson:gson:2.8.5'
|
- 第一步:定义实体类 (Java Bean) 类中的属性名需要与 JSON 数据中的键(key)保持一致。
- 第二步:解析 JSON 字符串
- 解析单个对象:
| ```java
Gson gson = new Gson();
App app = gson.fromJson(jsonData, App.class);
```
|
- 解析 JSON 数组 (包含多个对象):
| ```java
Gson gson = new Gson();
// 借助 TypeToken 获取泛型集合类型
List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>(){}.getType());
for (App app : appList) {
// 遍历处理每个对象
}
```
|