睿诚科技协会

Android如何访问网络?

在Android开发中,网络访问是核心功能之一,它允许应用从服务器获取数据、上传用户信息或与云端服务交互,由于Android系统的安全机制和网络环境的复杂性,开发者需要遵循特定的规范和最佳实践来实现稳定、高效的网络请求,本文将详细解析Android网络访问的关键技术、实现方式及注意事项。

Android如何访问网络?-图1
(图片来源网络,侵删)

网络访问的基础权限与配置

在Android中,应用访问网络首先需要在AndroidManifest.xml文件中声明网络权限,对于Android 6.0(API 23)及以上版本,还需动态申请运行时权限,具体配置如下:

<uses-permission android:name="android.permission.INTERNET" />
<!-- 如果需要使用网络状态,可添加 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

对于Android 9.0(API 28)及以上系统,默认禁止HTTP明文传输,建议使用HTTPS,若必须使用HTTP,需在application标签中添加android:usesCleartextTraffic="true"

主流网络请求方式对比

Android中常用的网络请求方式包括HttpURLConnection、OkHttp和Retrofit,以下是它们的特性对比:

方式 优点 缺点 适用场景
HttpURLConnection 系统原生,无需额外依赖,适合简单请求 API较繁琐,不支持异步请求(需配合Handler) 轻量级请求、学习场景
OkHttp 高效异步请求、支持连接池、拦截器、WebSocket 需额外引入依赖(com.squareup.okhttp3:okhttp 中大型项目,需高性能和扩展性
Retrofit 基于OkHttp,通过接口定义API,支持RxJava等 学习成本较高,依赖较多 复杂接口调用、需要与MVVM等架构结合

使用HttpURLConnection实现GET请求

URL url = new URL("https://api.example.com/data");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
    InputStream inputStream = connection.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder response = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        response.append(line);
    }
    reader.close();
    Log.d("Network", "Response: " + response.toString());
}
connection.disconnect();

使用OkHttp实现异步POST请求

首先添加依赖:

Android如何访问网络?-图2
(图片来源网络,侵删)
implementation 'com.squareup.okhttp3:okhttp:4.9.3'

然后实现异步请求:

OkHttpClient client = new OkHttpClient();
RequestBody body = FormBody.Builder()
    .add("key1", "value1")
    .add("key2", "value2")
    .build();
Request request = new Request.Builder()
    .url("https://api.example.com/submit")
    .post(body)
    .build();
client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.e("Network", "Request failed: " + e.getMessage());
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            Log.d("Network", "Response: " + response.body().string());
        }
    }
});

使用Retrofit简化API调用

首先添加依赖:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

定义接口:

public interface ApiService {
    @POST("submit")
    Call<ResponseBody> submitData(@Body RequestBody body);
}

初始化R并发起请求:

Android如何访问网络?-图3
(图片来源网络,侵删)
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();
ApiService service = retrofit.create(ApiService.class);
RequestBody body = FormBody.Builder()
    .add("key1", "value1")
    .build();
Call<ResponseBody> call = service.submitData(body);
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onFailure(Call call, Throwable t) {
        Log.e("Network", "Request failed: " + t.getMessage());
    }
    @Override
    public void onResponse(Call call, Response response) {
        if (response.isSuccessful()) {
            Log.d("Network", "Response: " + response.body());
        }
    }
});

网络请求的最佳实践

  1. 线程管理:网络请求必须在子线程中执行,避免阻塞主线程导致ANR,可通过AsyncTaskThread配合Handler,或使用ExecutorService管理线程池。
  2. 数据解析:常用解析库包括Gson(JSON)、FastXml(XML)、Protobuf(二进制),例如使用Gson解析JSON:
    Gson gson = new Gson();
    User user = gson.fromJson(jsonString, User.class);
  3. 错误处理:需处理网络异常(如SocketTimeoutException)、解析异常(如JsonSyntaxException)及HTTP错误状态码(如404、500)。
  4. 安全性:使用HTTPS防止数据泄露,对敏感数据进行加密(如AES),避免在URL中暴露明文参数。
  5. 性能优化:通过连接池复用TCP连接,使用缓存减少重复请求(如OkHttp的Cache),合理设置超时时间。

网络访问的常见问题与解决方案

  1. 主线程网络请求:直接在主线程调用网络请求会抛出NetworkOnMainThreadException,解决方案:将网络请求逻辑移至子线程,或使用runOnUiThread更新UI。
  2. 网络权限问题:Android 6.0+需动态申请权限,否则可能导致请求失败,解决方案:在ActivityFragment中检查并请求权限:
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) 
        != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, 
            new String[]{Manifest.permission.INTERNET}, 1);
    }

相关问答FAQs

Q1: 为什么在Android 9.0及以上版本使用HTTP会失败?
A: Android 9.0(API 28)默认禁止HTTP明文传输,以提升安全性,解决方案包括:将服务端升级为HTTPS;若必须使用HTTP,需在AndroidManifest.xmlapplication标签中添加android:usesCleartextTraffic="true"(不推荐,存在安全风险)。

Q2: 如何处理网络请求中的图片加载?
A: 图片加载需考虑内存占用和缓存策略,推荐使用Glide或Picasso库,它们支持内存缓存、磁盘缓存及自动回收内存,例如使用Glide加载图片:

Glide.with(context)
    .load("https://example.com/image.jpg")
    .into(imageView);
分享:
扫描分享到社交APP
上一篇
下一篇