安卓开发入门:如何从网页获取并解析JSON数据**
在安卓应用开发中,从网页获取JSON(JavaScript Object Notation)数据是一种非常常见的操作,JSON因其轻量级、易读和易于解析的特性,成为了Web服务与应用之间数据交换的主流格式,本文将详细介绍如何在安卓应用中通过网络请求获取JSON数据,并解析使用这些数据。
准备工作:添加网络权限
在安卓应用中访问网络,首先需要在AndroidManifest.xml文件中添加网络权限,打开你的app/src/main/AndroidManifest.xml文件,在<manifest>标签内添加以下权限声明:
<uses-permission android:name="android.permission.INTERNET" />
注意:从Android 9 (API 28)开始,默认情况下,明文流量(HTTP)是被禁止的,如果你的目标API级别是28或更高,但需要连接的网站只支持HTTP,你可以在<application>标签内添加android:usesCleartextTraffic="true"属性,或者更推荐的做法是让网站支持HTTPS。
<application
...
android:usesCleartextTraffic="true">
...
</application>
选择网络请求库
安卓原生提供了HttpURLConnection和HttpClient(已废弃)来进行网络请求,但它们使用起来相对繁琐,为了简化开发并提高效率,开发者通常会选择第三方网络请求库,如:
- Volley:Google推出的网络通信库,非常适合数据量不大、通信频繁的场景,图片加载和缓存功能强大。
- OkHttp:一个高效的HTTP客户端,支持HTTP/2、SPDY、连接池,在处理大文件和复杂网络请求时表现优异。
- Retrofit:基于OkHttp的一个类型安全的RESTful HTTP客户端客户端,通过注解方式配置网络参数,非常适合与JSON解析库(如Gson、Moshi)配合使用,能极大提升开发效率。
本文将以OkHttp + Gson为例进行讲解,因为它们是当前非常流行且强大的组合,如果你对Volley或Retrofit感兴趣,也可以自行查阅相关文档。
添加依赖
在项目的build.gradle (Module: app)文件中,添加OkHttp和Gson的依赖:
dependencies {
// OkHttp
implementation("com.squareup.okhttp3:okhttp:4.12.0") // 请使用最新版本
// Gson
implementation("com.google.code.gson:gson:2.10.1") // 请使用最新版本
}
添加完成后,点击“Sync Now”同步项目。
从网页获取JSON数据
假设我们要从一个公开的JSON API(https://jsonplaceholder.typicode.com/posts/1)获取数据,这个API返回一个JSON对象,格式如下:
{
"userId": 1,
"id": 1,: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
使用OkHttp进行GET请求
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class JsonFetcher {
private static final String JSON_URL = "https://jsonplaceholder.typicode.com/posts/1";
public static void fetchJsonData(final OnJsonDataFetchedListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(JSON_URL)
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
String responseData = response.body().string();
// 成功获取数据,通过回调传递
listener.onSuccess(responseData);
} else {
// 请求失败
listener.onFailure("Failed to fetch data: " + response.code());
}
} catch (IOException e) {
// 网络异常
listener.onFailure("Error: " + e.getMessage());
}
}
}).start();
}
// 定义回调接口
public interface OnJsonDataFetchedListener {
void onSuccess(String jsonData);
void onFailure(String errorMessage);
}
}
重要提示:网络操作不能在主线程(UI线程)中进行,否则会抛出NetworkOnMainThreadException异常,我们通常使用Thread、AsyncTask(已废弃)、ExecutorService或者更现代的Coroutine(Kotlin)或RxJava来在后台线程执行网络请求,上面的例子使用了Thread。
解析JSON数据
获取到JSON字符串后,我们需要将其解析成安卓可以使用的对象,Gson库可以非常方便地完成这项工作。
创建与JSON结构对应的Java/Kotlin类
根据上面示例JSON的结构,我们创建一个Post类:
// Java
public class Post {
private int userId;
private int id;
private String title;
private String body;
// 需要一个无参构造函数
public Post() {
}
// 可以添加getter和setter方法
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
// 重写toString方法方便打印日志
@Override
public String toString() {
return "Post{" +
"userId=" + userId +
", id=" + id +
", title='" + title + '\'' +
", body='" + body + '\'' +
'}';
}
}
使用Gson解析JSON字符串
我们在获取到JSON数据后,使用Gson将其解析为Post对象。
假设我们在一个Activity中调用JsonFetcher:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
public class MainActivity extends AppCompatActivity implements JsonFetcher.OnJsonDataFetchedListener {
private TextView textViewJsonData;
private Gson gson = new Gson();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewJsonData = findViewById(R.id.textViewJsonData);
// 调用方法获取JSON数据
JsonFetcher.fetchJsonData(this);
}
@Override
public void onSuccess(String jsonData) {
// 在主线程更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
// 使用Gson解析JSON字符串为Post对象
Post post = gson.fromJson(jsonData, Post.class);
// 将解析后的数据显示在TextView上
if (post != null) {
textViewJsonData.setText(post.toString());
// 或者单独显示某个字段
// textViewJsonData.setText("Title: " + post.getTitle());
}
} catch (Exception e) {
e.printStackTrace();
textViewJsonData.setText("解析JSON失败: " + e.getMessage());
}
}
});
}
@Override
public void onFailure(String errorMessage) {
// 在主线程显示错误信息
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
textViewJsonData.setText("获取数据失败: " + errorMessage);
}
});
}
}
确保你的activity_main.xml中有一个TextView,其id为textViewJsonData:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/textViewJsonData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="等待数据..."
android:textSize="16sp"/>
</LinearLayout>
处理更复杂的JSON结构
如果JSON是一个数组,
[
{"userId": 1, "id": 1, "title": "...", "body": "..."},
{"userId": 1, "id": 2, "title": "...", "body": "..."}
]
那么你的Java类应该是一个List,例如List<Post>,解析时只需改变第二个参数:
List<Post> posts



还没有评论,来说两句吧...