Android——通过okhttp进行网络请求
ifest文件,网络权限申请:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.myapplication"> <!-- 互联网 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 存储卡 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RadioGroup android:id="@+id/rg_method" android:layout_width="match_parent" android:layout_height="30dp" android:orientation="horizontal"> <RadioButton android:id="@+id/rb_get" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:checked="true" android:gravity="left|center" android:text="GET方式" android:textColor="@color/black" android:textSize="16sp" /> <RadioButton android:id="@+id/rb_post_form" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:checked="false" android:gravity="left|center" android:text="表单POST" android:textColor="@color/black" android:textSize="16sp" /> <RadioButton android:id="@+id/rb_post_json" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:checked="false" android:gravity="left|center" android:text="JSON POST" android:textColor="@color/black" android:textSize="16sp" /> </RadioGroup> <LinearLayout android:id="@+id/ll_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="5dp" android:paddingRight="5dp" android:orientation="vertical" android:visibility="gone"> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="用户名:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_username" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/editext_selector" android:gravity="left|center" android:hint="请输入用户名" android:maxLength="11" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="10dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="密 码:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_password" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/editext_selector" android:gravity="left|center" android:hint="请输入密码" android:inputType="numberPassword" android:maxLength="6" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> </LinearLayout> <Button android:id="@+id/btn_send" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发起接口调用" android:textColor="@color/black" android:textSize="17sp" /> <TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="5dp" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
NetConst
package com.example.myapplication; public class NetConst { // HTTP地址的前缀 public final static String HTTP_PREFIX = "http://192.168.1.7:8080/HttpServer/"; // WebSocket服务的前缀 public final static String WEBSOCKET_PREFIX = "ws://192.168.1.7:8080/HttpServer/"; public final static String BASE_IP = "192.168.1.7"; // 基础Socket服务的ip public final static int BASE_PORT = 9010; // 基础Socket服务的端口 public final static String CHAT_IP = "192.168.1.7"; // 聊天Socket服务的ip public final static int CHAT_PORT = 9011; // 聊天Socket服务的端口 }
activity:
package com.example.myapplication; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RadioGroup; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import org.json.JSONObject; import java.io.IOException; import okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; public class MainActivity extends AppCompatActivity { private final static String TAG = "OkhttpCallActivity"; private final static String URL_STOCK = "https://hq.sinajs.cn/list=s_sh000001"; private final static String URL_LOGIN = NetConst.HTTP_PREFIX + "login"; private LinearLayout ll_login; // 声明一个线性布局对象 private EditText et_username; // 声明一个编辑框对象 private EditText et_password; // 声明一个编辑框对象 private TextView tv_result; // 声明一个文本视图对象 private int mCheckedId = R.id.rb_get; // 当前选中的单选按钮资源编号 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ll_login = findViewById(R.id.ll_login); et_username = findViewById(R.id.et_username); et_password = findViewById(R.id.et_password); tv_result = findViewById(R.id.tv_result); RadioGroup rg_method = findViewById(R.id.rg_method); rg_method.setOnCheckedChangeListener((group, checkedId) -> { mCheckedId = checkedId; int visibility = mCheckedId == R.id.rb_get ? View.GONE : View.VISIBLE; ll_login.setVisibility(visibility); }); findViewById(R.id.btn_send).setOnClickListener(v -> { if (mCheckedId == R.id.rb_get) { doGet(); // 发起GET方式的HTTP请求 } else if (mCheckedId == R.id.rb_post_form) { postForm(); // 发起POST方式的HTTP请求(报文为表单格式) } else if (mCheckedId == R.id.rb_post_json) { postJson(); // 发起POST方式的HTTP请求(报文为JSON格式) } }); } // 发起GET方式的HTTP请求 private void doGet() { OkHttpClient client = new OkHttpClient(); // 创建一个okhttp客户端对象 // 创建一个GET方式的请求结构 Request request = new Request.Builder() //.get() // 因为OkHttp默认采用get方式,所以这里可以不调get方法 .header("Accept-Language", "zh-CN") // 给http请求添加头部信息 .header("Referer", "https://finance.sina.com.cn") // 给http请求添加头部信息 .url(URL_STOCK) // 指定http请求的调用地址 .build(); Call call = client.newCall(request); // 根据请求结构创建调用对象 // 加入HTTP请求队列。异步调用,并设置接口应答的回调方法 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 请求失败 // 回到主线程操纵界面 runOnUiThread(() -> tv_result.setText("调用股指接口报错:"+e.getMessage())); } @Override public void onResponse(Call call, final Response response) throws IOException { // 请求成功 String resp = response.body().string(); // 回到主线程操纵界面 runOnUiThread(() -> tv_result.setText("调用股指接口返回:\n"+resp)); } }); } // 发起POST方式的HTTP请求(报文为表单格式) private void postForm() { String username = et_username.getText().toString(); String password = et_password.getText().toString(); // 创建一个表单对象 FormBody body = new FormBody.Builder() .add("username", username) .add("password", password) .build(); OkHttpClient client = new OkHttpClient(); // 创建一个okhttp客户端对象 // 创建一个POST方式的请求结构 Request request = new Request.Builder().post(body).url(URL_LOGIN).build(); Call call = client.newCall(request); // 根据请求结构创建调用对象 // 加入HTTP请求队列。异步调用,并设置接口应答的回调方法 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 请求失败 // 回到主线程操纵界面 runOnUiThread(() -> tv_result.setText("调用登录接口报错:"+e.getMessage())); } @Override public void onResponse(Call call, final Response response) throws IOException { // 请求成功 String resp = response.body().string(); // 回到主线程操纵界面 runOnUiThread(() -> tv_result.setText("调用登录接口返回:\n"+resp)); } }); } // 发起POST方式的HTTP请求(报文为JSON格式) private void postJson() { String username = et_username.getText().toString(); String password = et_password.getText().toString(); String jsonString = ""; try { JSONObject jsonObject = new JSONObject(); jsonObject.put("username", username); jsonObject.put("password", password); jsonString = jsonObject.toString(); } catch (Exception e) { e.printStackTrace(); } // 创建一个POST方式的请求结构 RequestBody body = RequestBody.create(jsonString, MediaType.parse("text/plain;charset=utf-8")); OkHttpClient client = new OkHttpClient(); // 创建一个okhttp客户端对象 Request request = new Request.Builder().post(body).url(URL_LOGIN).build(); Call call = client.newCall(request); // 根据请求结构创建调用对象 // 加入HTTP请求队列。异步调用,并设置接口应答的回调方法 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 请求失败 // 回到主线程操纵界面 runOnUiThread(() -> tv_result.setText("调用登录接口报错:"+e.getMessage())); } @Override public void onResponse(Call call, final Response response) throws IOException { // 请求成功 String resp = response.body().string(); // 回到主线程操纵界面 runOnUiThread(() -> tv_result.setText("调用登录接口返回:\n"+resp)); } }); } }