当前位置: 首页 > news >正文

Android网络请求,Retrofit,OKHttp学习

Retrofit、OkHttp(层网络请求,拦截器处理 Header、缓存)、子线程处理相关事务

1.WebView

WebView可以在我们自己的应用程序中嵌入一个浏览器并且展示网页

新建一个项目,修改主活动布局代码

<?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"><WebViewandroid:id="@+id/web_view"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

可以看到在布局中使用了WebView,修改MainActivity

package com.example.webviewtest;import android.os.Bundle;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;import android.webkit.WebView;
import android.webkit.WebViewClient;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);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");}
}

MainActivity中,首先获取WebView实例,调用WebView的getSettings()方法可以设置一些浏览器的属性,调用setJavaScriptEnabled()方法来让WebView支持javaScript脚本。

调用WebView的setWebViewClient()方法,并传入一个WebViewClinet实例。这段代码的作用是,当需要从一个网页跳转到另一个网页时,我们希望目标王爷仍然在当前WebView中显示,而不是打开浏览器。

WebView的loadUrl()方法将网址传入,就可以展示网页的内容,这里就让我们来看一看百度的首页。

由于本程序使用了网络功能,所以需要申请权限

2使用HTTP协议访问网络

  • HTTP 协议基础:客户端发请求,服务器返回数据,客户端解析处理,浏览器(含 WebView )依此工作。
  • WebView 示例:向百度服务器发 HTTP 请求,服务器返回百度首页 HTML 代码,WebView 调用手机浏览器内核解析展示。
  • WebView 特点与不足:后台处理发请求、收响应、解析数据、展示页面,因封装好,难直观看到 HTTP 协议工作过程,故需手动发请求深入理解 。

2.1使用HttpURLConnection

  1. 获取 HttpURLConnection 实例:通过 new URL() 传入目标网络地址创建 URL 对象,再调用 openConnection() 方法并强转为 HttpURLConnection 类型,得到其实例 。

    URL url = new URL("http://www.baidu.com");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    
  2. 设置 HTTP 请求方法:得到实例后,可用 setRequestMethod() 设置,常用 GET(从服务器获取数据 )和 POST(向服务器提交数据 )。

    connection.setRequestMethod("GET");
    
  3. 定制连接参数:可通过 setConnectTimeout()(设置连接超时 )、setReadTimeout()(设置读取超时 )等方法,依据实际需求定制。

    connection.setConnectTimeout(8000);
    connection.setReadTimeout(8000);
    
  4. 获取与处理服务器响应:调用 getInputStream() 获取服务器返回的输入流,后续需读取流中数据;操作完成后,用 disconnect() 关闭 HTTP 连接 。

    InputStream in = connection.getInputStream();
    connection.disconnect();
    

示例:新建一个NetWorkTest项目

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/send_request"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="发送请求" /><ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/response_text"android:layout_width="match_parent"android:layout_height="wrap_content" /></ScrollView></LinearLayout>
package com.example.networktest;import android.os.Bundle;
import android.view.View;
import android.widget.TextView;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;public class MainActivity extends AppCompatActivity implements View.OnClickListener {TextView responseText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);View button = findViewById(R.id.send_request);responseText = findViewById(R.id.response_text);button.setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.send_request) {sendRequestWithHttpURLConnection();}}private void sendRequestWithHttpURLConnection(){//开启线程来发起网络请求new Thread(new Runnable() {@Overridepublic 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();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 (Exception e){e.printStackTrace();}}if (connection != null){connection.disconnect();}}}}).start();}private void showResponse(final String response) {runOnUiThread(new Runnable() {@Overridepublic void run() {//在UI线程中显示响应内容responseText.setText(response);}});}
}

请求成功 在这里插入图片描述

可以成功看到服务器返回给我们的HTML代码。

提交数据也很简单,只需要将Http请求的方法改成POST,并在获取输入流之前把要提交的数据写出即可。注意每条数据都要以键值对的形式存在,数据和数据之间用&隔开,比如我们想要向服务器提交用户名和密码,就可以

connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username = admin&password = 123456");

2.2使用OkHttp

现在时广大Android开发者的首选网络通信库。

在使用OKHttp之前需要在项目中添加OkHttp库的依赖。编辑app/build.gradle在dependencies闭包下添加

    implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'com.android.support:appcompat-v7:24.2.1'testImplementation 'junit:junit:4.12'implementation 'com.squareup.okhttp3:okhttp:3.4.1'

添加上述依赖自动下载两个库一个OkHttp,一个是Okio库,后者是前者通信的基础。

  1. OkHttp 基本使用流程

    • 创建客户端实例:通过 new OkHttpClient() 创建 OkHttpClient 实例,作为发起请求的客户端。

    • OkHttpClient client = new OkHttpClient();
      
    • 构建请求对象(Request):利用 Request.Builder 构建 Request 对象,可通过 url() 方法设置目标网络地址,若为 POST 请求,还需构建 RequestBody 存放参数,并用 post() 方法传入。

    • Request request = new Request.Builder().url("http://www.baidu.com").build();
      
    • 发起请求并获取响应:调用 OkHttpClientnewCall() 方法创建 Call 对象,再调用 execute() 发送请求,获取 Response 响应对象,从响应对象中可提取服务器返回数据。

    • Response response = client.newCall(request).execute();
      String responseData = response.body().string();
      
  2. GET 请求关键步骤:构建 Request 时用 url() 设地址,无需额外参数体,直接发起请求获取响应。

  3. POST 请求关键步骤:先通过 FormBody.Builder 构建 RequestBody 存放参数(如用户名、密码 ),再在 Request.Builder 中用 post() 方法传入该 RequestBody ,之后流程同 GET 请求。

    // 构建请求参数体
    RequestBody requestBody = new FormBody.Builder().add("username", "admin").add("password", "123456").build();
    // 构建包含 POST 参数的请求
    Request request = new Request.Builder().url("http://www.baidu.com").post(requestBody).build();
    

直接在前面的项目上做修改

package com.example.networktest;import android.os.Bundle;
import android.view.View;
import android.widget.TextView;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okio.Okio;public class MainActivity extends AppCompatActivity implements View.OnClickListener {TextView responseText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);View button = findViewById(R.id.send_request);responseText = findViewById(R.id.response_text);button.setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.send_request) {sendRquestWithOkHttp();}}private void sendRquestWithOkHttp() {new Thread(new Runnable() {@Overridepublic 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 sendRequestWithHttpURLConnection(){//开启线程来发起网络请求new Thread(new Runnable() {@Overridepublic 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();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 (Exception e){e.printStackTrace();}}if (connection != null){connection.disconnect();}}}}).start();}private void showResponse(final String response) {runOnUiThread(new Runnable() {@Overridepublic void run() {//在UI线程中显示响应内容responseText.setText(response);}});}
}

这里并没有做太大的改动,添加一个sendRequestWithOkHttp()方法,用OkHttp 的方式来实现了之前的Http请求

在这里插入图片描述

同样得到结果。

3.Retrofit

准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。
原因:网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装本质过程

App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作
在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析

使用介绍

步骤1:添加Retrofit库的依赖

compile 'com.squareup.retrofit2:retrofit:2.0.2'

步骤2:创建 接收服务器返回数据 的类
步骤3:创建 用于描述网络请求 的接口
步骤4:创建 Retrofit 实例
步骤5:创建 网络请求接口实例 并 配置网络请求参数
步骤6:发送网络请求(异步 / 同步)
步骤7:处理服务器返回的数据

学习URL整合规则

package com.example.networktest;import java.util.List;public class Translation1 {private String type;private int errorCode;private int elapsedTime;private List<List<TranslateResultBean>> translateResult;public String getType() {return type;}public void setType(String type) {this.type = type;}public int getErrorCode() {return errorCode;}public void setErrorCode(int errorCode) {this.errorCode = errorCode;}public int getElapsedTime() {return elapsedTime;}public void setElapsedTime(int elapsedTime) {this.elapsedTime = elapsedTime;}public List<List<TranslateResultBean>> getTranslateResult() {return translateResult;}public void setTranslateResult(List<List<TranslateResultBean>> translateResult) {this.translateResult = translateResult;}public static class TranslateResultBean {/*** src : merry me* tgt : 我快乐*/public String src;public String tgt;public String getSrc() {return src;}public void setSrc(String src) {this.src = src;}public String getTgt() {return tgt;}public void setTgt(String tgt) {this.tgt = tgt;}}}
package com.example.networktest;import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;public interface PostRequest_Interface {@POST("mtpe-individual/transText?aldtype=16047&ext_channel=Aldtype#/auto/zh")@FormUrlEncodedCall<Translation1> getCall(@Field("i") String targetSentence);//采用@Post表示Post方法进行请求(传入部分url地址)// 采用@FormUrlEncoded注解的原因:API规定采用请求格式x-www-form-urlencoded,即表单形式// 需要配合@Field 向服务器提交需要的字段
}
package com.example.networktest;import static android.content.ContentValues.TAG;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;public class PostRequest extends AppCompatActivity implements View.OnClickListener {private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = findViewById(R.id.send_request);button.setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.send_request) {request();}}public void request() {//步骤4:创建Retrofit对象Retrofit retrofit = new Retrofit.Builder().baseUrl("https://fanyi.baidu.com/") // 设置 网络请求 Url.addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖).build();// 步骤5:创建 网络请求接口 的实例PostRequest_Interface request = retrofit.create(PostRequest_Interface.class);//对 发送请求 进行封装(设置需要翻译的内容)Call<Translation1> call = request.getCall("I love you");//步骤6:发送网络请求(异步)call.enqueue(new Callback<Translation1>() {//请求成功时回调@Overridepublic void onResponse(Call<Translation1> call, Response<Translation1> response) {// 步骤7:处理返回的数据结果:输出翻译的内容Log.d(TAG, "onResponse: "+response.body().getTranslateResult().get(0).get(0).getTgt());}//请求失败时回调@Overridepublic void onFailure(Call<Translation1> call, Throwable throwable) {Log.d(TAG, "onFailure: "+throwable.getMessage());}});}}
http://www.dtcms.com/a/295172.html

相关文章:

  • SAP调用外部API
  • MST技术加持,简化桌面多屏布局
  • 题解:P9468 [EGOI 2023] Candy / 糖果
  • GNSS差分定位系统之一:差分定位中的单差和双差
  • Java【代码 03】未分页数据根据参数进行后期分页(粘贴可用)
  • git 修改最近一次 commit 信息
  • Prometheus介绍
  • 部署zabbix
  • Git版本控制系统
  • 什么是MySQL 视图
  • CSS预处理器与后处理器对比解析
  • 我用EV-21569-SOM评估来开发ADSP-21569(十二)-SigmaStudio Plus做开发(3)
  • Element中ElMessageBox弹框内容及按钮样式自定义
  • 论文解析 基于遗传算法增强YOLOv5算法的合成数据风力涡轮叶片缺陷检测
  • 面试150 环形子数组的最大和
  • StringBuilder学习
  • Python 程序设计讲义(8):Python 的基本数据类型——浮点数
  • 【faiss】用于高效相似性搜索和聚类的C++库 | 源码详解与编译安装
  • C基础 07_综合案例《猜拳游戏》
  • 机器学习与视觉结合开发基础
  • IPTV电视直播源更新工具和检测直播源工具
  • Python打卡Day22 kaggle泰坦尼克号生存预测
  • 基于Informer+BiGRU-GAtt的并行预测模型
  • Java开发岗面试记录合集
  • 二分查找----3.在排序数组中查找元素的第一个和最后一个位置
  • 语音增强相关技术
  • 【世纪龙科技】新能源汽车维护与故障诊断-汽车专业数字课程资源
  • 第八讲:C++中的vector
  • Ⅹ—6.计算机二级综合题5---6套
  • Fast Frequency Estimation Algorithm by Least Squares Phase Unwrapping