安卓:网络框架okhttp

news2025/1/13 7:54:16

目录

一、okhttp介绍

1. OkHttpClient类:

 常用方法:

2. Request类:

 常用方法:

3. Response类:

常用方法:

4. Call类:

常用方法: 

5. Interceptor接口:

常用方法: 

6. FormBody类:

常用方法:

7. MultipartBody类:

 常用方法:

8. WebSocket类:

常用方法:

二、okhttp使用方法

1、添加依赖:

2、创建OkHttpClient对象:

3、创建Request对象:

4、发送同步请求: 

5、发送异步请求 

三、okhttp例子

省的json数据格式: 

 市的json数据格式: 

 县的json数据格式:

 MainActivity:

 Utility :

 HttpTool :

Province : 

 City:

County : 

activity_main: 

litepal.xml: 

AndroidManifest: 

依赖: 

运行结果:

一、okhttp介绍

        OkHttp是一个开源的HTTP客户端库,常用于Android应用程序中进行网络请求。以下是OkHttp的一些常用类和方法:

1. OkHttpClient类:

        OkHttpClient是OkHttp库的核心类,用于创建和配置HTTP请求的客户端。它提供了各种设置和配置选项,如连接超时、读写超时、拦截器等。

 常用方法:

  • newBuilder()创建一个新的OkHttpClient.Builder实例,用于配置和构建OkHttpClient对象。

  • addInterceptor(Interceptor interceptor)添加一个Interceptor拦截器,用于在发送请求和接收响应时对其进行处理。例如,可以使用拦截器对请求进行身份验证、日志记录或数据转换等操作。

  • connectTimeout(long timeout, TimeUnit unit)设置连接超时时间。可以指定一个时间值和时间单位来限制与服务器建立连接的最长时间。

  • readTimeout(long timeout, TimeUnit unit)设置读取超时时间。可以指定一个时间值和时间单位来限制从服务器读取数据的最长时间。

  • writeTimeout(long timeout, TimeUnit unit)设置写入超时时间。可以指定一个时间值和时间单位来限制向服务器写入数据的最长时间。

  • retryOnConnectionFailure(boolean retry)设置是否重试连接失败的请求。默认情况下,OkHttpClient会自动重试请求,但可以通过该方法禁用重试。

  • followRedirects(boolean followRedirects)设置是否自动遵循重定向。默认情况下,OkHttpClient会自动遵循重定向,但可以通过该方法禁用自动重定向。

  • cache(Cache cache)设置缓存。可以传入一个Cache对象,用于缓存网络请求的响应数据。

  • dispatcher(Dispatcher dispatcher)设置Dispatcher调度器。可以传入一个自定义的Dispatcher对象,用于控制并发请求数量和线程池的行为。

  • proxy(Proxy proxy)设置代理服务器。可以指定一个Proxy对象,用于将请求通过代理发送到目标服务器。

2. Request类:

        Request类用于构建HTTP请求。可以通过Request.Builder来创建一个Request对象,并设置URL、请求方法(GET、POST等)、请求头、请求体等。

 常用方法:

  • newBuilder()创建一个新的Request.Builder实例,用于构建和配置Request对象。

  • url(String url)设置请求的URL地址。可以传入一个字符串类型的URL地址作为参数。

  • method(String method, RequestBody body)设置请求的HTTP方法和请求体。可以指定请求的HTTP方法(如GET、POST、PUT等)和请求体RequestBody对象。

  • header(String name, String value)添加请求头。可以通过该方法添加自定义的请求头参数,需要提供参数名和参数值。

  • headers(Headers headers)设置请求头集合。可以通过该方法一次性设置多个请求头,需要传入Headers对象。

  • cacheControl(CacheControl cacheControl)设置缓存控制策略。可以传入一个CacheControl对象,用于控制请求的缓存行为。

  • tag(Object tag)设置请求的标签。可以传入一个Object类型的标签,用于在后续操作中标识和识别该请求。

  • build()构建Request对象。在配置完成后,使用该方法来构建最终的Request对象。

3. Response类:

        Response类表示HTTP响应。当发送HTTP请求后,可以通过Response对象获取服务器返回的响应信息,包括状态码、响应头、响应体等。

常用方法:

  • code()获取HTTP响应的状态码。返回一个整型值,表示HTTP响应的状态码。

  • message()获取HTTP响应的状态消息。返回一个字符串,表示HTTP响应的状态消息。

  • body()获取HTTP响应的响应体。返回一个ResponseBody对象,用于获取和处理响应的具体数据。

  • headers()获取HTTP响应的响应头。返回一个Headers对象,用于获取和处理响应的头部信息。

  • isSuccessful()判断HTTP响应是否成功。返回一个布尔值,表示HTTP响应是否成功(状态码在200-299之间)。

  • cacheResponse()获取缓存的HTTP响应。如果请求使用了缓存,并且有对应的缓存响应,则返回一个Response对象,否则返回null。

  • networkResponse()获取网络的HTTP响应。如果请求是通过网络发送的,并且有对应的网络响应,则返回一个Response对象,否则返回null。

  • priorResponse()获取前一个HTTP响应。如果请求有关联的前一个HTTP响应,则返回一个Response对象,否则返回null。

  • request()获取与该HTTP响应相关联的请求。返回一个Request对象,表示与该响应相关联的请求。

4. Call类:

        Call类表示一个异步的HTTP请求任务。通过OkHttpClient的newCall方法创建一个Call对象,然后可以使用enqueue方法发送异步请求,并通过回调函数处理响应结果。

常用方法: 

  • execute()同步执行HTTP请求并返回Response对象。该方法会阻塞当前线程,直到获取到完整的响应结果。

  • enqueue(Callback callback)异步执行HTTP请求并通过回调函数接收结果。该方法将请求放入请求队列中,并在后台线程执行,执行完成后通过Callback接口回调返回结果。

  • cancel()取消HTTP请求。如果HTTP请求尚未执行完毕,可以调用该方法取消正在进行的请求。

  • isExecuted()判断HTTP请求是否已经执行。返回一个布尔值,表示HTTP请求是否已经执行。

  • isCanceled()判断HTTP请求是否已经取消。返回一个布尔值,表示HTTP请求是否已经取消。

  • timeout()获取超时设置。返回一个Timeout对象,用于获取和设置连接、读取和写入的超时时间。

  • request()获取与该Call相关联的请求。返回一个Request对象,表示与该Call相关联的HTTP请求。

  • clone()创建Call对象的副本。返回一个新的Call对象,与原始的Call对象共享相同的配置和请求信息。

5. Interceptor接口:

        Interceptor接口可以用于对HTTP请求和响应进行拦截和处理。可以实现自定义的Interceptor来对请求进行修改、添加请求头、记录日志等操作。

常用方法: 

  1. Response intercept(Chain chain)拦截并处理请求和响应。该方法接收一个Chain对象作为参数,可以通过该对象获取请求信息并执行下一个拦截器或者发起实际的网络请求。

  2. interface Chain表示拦截器链中的一环,用于传递请求和响应以及控制拦截器的执行流程。Chain接口拥有以下方法:

  • Connection connection():获取当前拦截器链的连接对象。
  • Request request():获取当前拦截器链的请求对象。
  • Response proceed(Request request):执行下一个拦截器,并返回最终的响应结果。

6. FormBody类:

        FormBody类是OkHttp库中用于构建表单形式的请求体的类。它提供了一些方法来添加表单字段和值,并生成最终的请求体数据。

常用方法:

  • add(String name, String value)添加表单字段和值。可以多次调用该方法,以添加多个表单字段和对应的值。

  • encodedName(int index)获取编码后的表单字段名。传入索引值,返回对应位置的编码后的表单字段名。

  • encodedValue(int index)获取编码后的表单字段值。传入索引值,返回对应位置的编码后的表单字段值。

  • name(int index)获取未编码的表单字段名。传入索引值,返回对应位置的未编码的表单字段名。

  • value(int index)获取未编码的表单字段值。传入索引值,返回对应位置的未编码的表单字段值。

  • size()获取表单字段的数量。返回一个整型值,表示表单字段的数量。

  • contentType():获取请求体的媒体类型。返回一个MediaType对象,表示请求体的媒体类型,默认为"application/x-www-form-urlencoded"。

  • contentLength()获取请求体的长度。返回一个长整型值,表示请求体的字节长度。

  • toString()将FormBody转换为字符串。返回一个字符串,表示FormBody的内容。

7. MultipartBody类:

       MultipartBody类是OkHttp库中用于构建多部分(multipart)请求体的类。它允许在单个请求中包含多个不同类型的数据,如文本、文件等。

 常用方法:

  • create(MediaType type, RequestBody... parts)创建一个MultipartBody对象。需要传入媒体类型和多个RequestBody实例。

  • type()获取请求体的媒体类型。返回一个MediaType对象,表示请求体的媒体类型,默认为"multipart/form-data"。

  • boundary()获取边界字符串。返回一个字符串,表示请求体的边界字符串。

  • contentType()获取请求体的完整媒体类型。返回一个字符串,表示请求体的完整媒体类型,包括媒体类型和边界字符串。

  • parts()获取请求体的各个部分。返回一个List<RequestBody>,表示请求体中的所有部分。

  • writeTo(BufferedSink sink)将MultipartBody写入到缓冲区。需要传入一个BufferedSink对象,用于写入请求体的数据。

  • contentLength()获取请求体的长度。返回一个长整型值,表示请求体的字节长度。

  • addPart(Headers headers, RequestBody body)添加一个部分到请求体中。可以传入自定义的请求头Headers对象和对应的RequestBody实例。

  • addFormDataPart(String name, @Nullable String filename, RequestBody body)添加一个表单数据部分到请求体中。需要传入字段名name、可选的文件名filename和RequestBody实例。

  • addFormDataPart(String name, @Nullable String filename, MediaType contentType, ByteString content)添加一个表单数据部分到请求体中。需要传入字段名name、可选的文件名filename、媒体类型contentType和内容content。

8. WebSocket类:

        WebSocket类用于进行WebSocket通信。可以建立与服务器的WebSocket连接,并进行双向通信。

常用方法:

  • request()获取与该WebSocket相关联的请求。返回一个Request对象,表示与该WebSocket相关联的HTTP请求。

  • queueSize()获取待发送的消息队列大小。返回一个整型值,表示待发送的消息队列中的消息数量。

  • send(String text)发送文本消息。可以传入一个字符串类型的消息内容,将其作为文本消息发送给服务器。

  • send(ByteString bytes)发送二进制消息。可以传入一个ByteString对象,将其作为二进制消息发送给服务器。

  • close(int code, String reason)关闭WebSocket连接。可以传入一个整型的关闭码(如1000表示正常关闭)、一个字符串的关闭原因,以便向服务器发送关闭帧,并关闭WebSocket连接。

  • cancel()取消WebSocket连接。如果WebSocket连接尚未关闭,可以调用该方法取消连接。

  • send(Request request, WebSocketListener listener)发送指定请求的WebSocket消息。可以传入一个Request对象和一个WebSocketListener对象,将该请求发送给服务器,并通过WebSocketListener监听回调处理结果。

  • addListener(WebSocketListener listener)添加WebSocket事件监听器。可以传入一个WebSocketListener对象,用于监听WebSocket连接状态、收到消息等事件。

  • removeListener(WebSocketListener listener)移除WebSocket事件监听器。可以传入一个WebSocketListener对象,将其从WebSocket的监听器列表中移除。

二、okhttp使用方法

1、添加依赖:

        在项目的build.gradle文件中添加OkHttp的依赖项。

 implementation 'com.squareup.okhttp3:okhttp:3.12.0'

2、创建OkHttpClient对象:

        通过new OkHttpClient()创建一个OkHttpClient实例,用于发送HTTP请求。

OkHttpClient client = new OkHttpClient();

3、创建Request对象:

        使用Request.Builder构建一个请求对象,并指定URL地址、请求头、请求体等相关信息。

Request request = new Request.Builder()
        .url("https://example.com/api")
        .header("Content-Type", "application/json")
        .post(RequestBody.create(MediaType.parse("application/json"), jsonBody))
        .build();

4、发送同步请求: 

        使用client.newCall(request).execute()发送同步请求,并获得Response对象。 

try (Response response = client.newCall(request).execute()) {
    // 处理响应结果
    if (response.isSuccessful()) {
        String responseBody = response.body().string();
        // ...
    } else {
        // 请求失败处理
    }
} catch (IOException e) {
    // IO异常处理
}

5、发送异步请求 

         使用client.newCall(request).enqueue(Callback)发送异步请求,并通过Callback回调处理响应结果。

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // 请求失败处理
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
    // 处理响应结果
        if (response.isSuccessful()) {
            String responseBody = response.body().string();
            // ...
        } else {
            // 请求失败处理
        }
    }
});

        在以上示例中,我们首先创建了一个OkHttpClient对象,并使用Request.Builder构建了一个请求对象。然后,可以选择性地发送同步或异步请求。对于同步请求,直接调用execute()方法并处理响应结果;对于异步请求,使用enqueue(Callback)方法并通过Callback回调处理响应结果。

        当处理完请求后,需要注意关闭Response对象的资源,以避免内存泄漏。

三、okhttp例子

        下面例子是郭霖大神的第一行代码中的酷欧天气网络请求地名的代码。 

省的json数据格式: 

http://guolin.tech/api/china

 

 市的json数据格式: 

 http://guolin.tech/api/china/16

 县的json数据格式:

 MainActivity:

package com.example.okhttpdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.okhttpdemo.Bean.City;
import com.example.okhttpdemo.Bean.County;
import com.example.okhttpdemo.Bean.Province;

import org.litepal.LitePal;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import okhttp3.internal.Util;

public class MainActivity extends AppCompatActivity {
    public static final int CURRENT_PAGE_PROVINCE = 0;
    public static final int CURRENT_PAGE_CITY = 1;
    public static final int CURRENT_PAGE_COUNTY = 2;
    private List<Province> mProvinces;
    private List<City> mCities;
    private List<County> mCounties;
    private TextView titleTV;
    private Button backBtn;
    private ListView mListView;
    private List<String> mListData = new ArrayList<>();
    private ArrayAdapter<String> mAdapter;
    private ProgressDialog progressDialog;
    private int currentPage;
    private Province mCurrentProvince;
    private City mCurrentCity;
    private County mCurrentCounty;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LitePal.initialize(this);
        initView();
    }

    private void initView() {
        mListView = findViewById(R.id.list_view);
        backBtn = findViewById(R.id.back_button);
        titleTV= findViewById(R.id.title_text);

        backBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (currentPage==CURRENT_PAGE_COUNTY){
                    queryCities();
                }else if(currentPage == CURRENT_PAGE_CITY){
                    queryProvinces();
                }
            }
        });
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                switch (currentPage){
                    case CURRENT_PAGE_PROVINCE:
                        mCurrentProvince = mProvinces.get(position);
                        queryCities();
                        break;
                    case CURRENT_PAGE_CITY:
                        mCurrentCity = mCities.get(position);
                        queryCounty();
                        break;
                    case CURRENT_PAGE_COUNTY:
                        mCurrentCounty = mCounties.get(position);
                        Toast.makeText(MainActivity.this,"点击了"+mCurrentProvince.getProvinceName()+mCurrentCity.getCityName()+mCurrentCounty.getCountyName(),Toast.LENGTH_LONG).show();
                        break;
                }
            }
        });
        mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mListData);
        queryProvinces();
        mListView.setAdapter(mAdapter);
    }
    
    private void queryProvinces(){

       titleTV.setText("中国");
       backBtn.setVisibility(View.GONE);
       // 从数据库中找
       mProvinces = LitePal.findAll(Province.class);
       if (mProvinces.size()>0){
           mListData.clear();
           for (Province province:mProvinces){
               mListData.add(province.getProvinceName());
           }
           mAdapter.notifyDataSetChanged();
           currentPage = CURRENT_PAGE_PROVINCE;
       }else {
           String url = "http://guolin.tech/api/china";
           queryFromServer(url,CURRENT_PAGE_PROVINCE);
       }
    }

    private void queryFromServer(String url, int type) {
        showProgressDialog();
        HttpTool.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        closeProgressDialog();
                        Toast.makeText(MainActivity.this,"加载失败!!!",Toast.LENGTH_LONG).show();
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                boolean result = false;
                switch (type){
                    case CURRENT_PAGE_PROVINCE:
                        result = Utility.handleProvinceResponse(response.body().string());
                        break;
                    case CURRENT_PAGE_CITY:
                        result = Utility.handleCitiesResponse(response.body().string(),mCurrentProvince.getId());
                        break;
                    case CURRENT_PAGE_COUNTY:
                        result = Utility.handleCountyResponse(response.body().string(),mCurrentCity.getId());
                        break;
                }
                if (result){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            closeProgressDialog();
                            switch (type){
                                case CURRENT_PAGE_PROVINCE:
                                    queryProvinces();
                                    break;
                                case CURRENT_PAGE_CITY:
                                    queryCities();
                                    break;
                                case CURRENT_PAGE_COUNTY:
                                    queryCounty();
                                    break;
                            }
                        }
                    });

                }
            }
        });
    }
    private void queryCounty() {
        titleTV.setText(mCurrentCity.getCityName());
        backBtn.setVisibility(View.VISIBLE);
        // 从数据库中找
        mCounties = LitePal.where("cityid=?",String.valueOf(mCurrentCity.getId())).find(County.class);
        if (mCounties.size()!=0){
            mListData.clear();
            for (County county:mCounties){
                mListData.add(county.getCountyName());
            }
            mAdapter.notifyDataSetChanged();
            currentPage = CURRENT_PAGE_COUNTY;
        }else {
            int provinceCode = mCurrentProvince.getProvinceCode();
            int citiCode = mCurrentCity.getCityCode();
            String url = "http://guolin.tech/api/china/" + provinceCode+"/"+citiCode;
            queryFromServer(url,CURRENT_PAGE_COUNTY);
        }
    }
    private void queryCities() {
        titleTV.setText(mCurrentProvince.getProvinceName());
        backBtn.setVisibility(View.VISIBLE);
        // 从数据库中找
        mCities = LitePal.where("provinceid=?",String.valueOf(mCurrentProvince.getId())).find(City.class);
        if (mCities.size()!=0){
            mListData.clear();
            for (City city:mCities){
                mListData.add(city.getCityName());
            }
            mAdapter.notifyDataSetChanged();
            currentPage = CURRENT_PAGE_CITY;
        }else {
            int provinceCode = mCurrentProvince.getProvinceCode();
            String url = "http://guolin.tech/api/china/" + provinceCode;
            queryFromServer(url,CURRENT_PAGE_CITY);
        }
    }
    /**
     * 显示进度对话框
     */
    private void showProgressDialog() {
        if (progressDialog == null) {
            progressDialog = new ProgressDialog(this);
            progressDialog.setMessage("正在加载...");
            progressDialog.setCanceledOnTouchOutside(false);
        }
        progressDialog.show();
    }
    /**
     * 关闭进度对话框
     */
    private void closeProgressDialog() {
        if (progressDialog != null) {
            progressDialog.dismiss();
        }
    }
}

 Utility :

package com.example.okhttpdemo;

import android.text.TextUtils;


import com.example.okhttpdemo.Bean.City;
import com.example.okhttpdemo.Bean.County;
import com.example.okhttpdemo.Bean.Province;
import com.google.gson.Gson;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class Utility {
/**
 * 解析和处理服务器返回的省级的数据
 */
public static boolean handleProvinceResponse(String response) {
    if (!TextUtils.isEmpty(response)) {
        try {
            JSONArray allProvinces = new JSONArray(response);
            for (int i = 0; i < allProvinces.length(); i++) {
                JSONObject provinceObject = allProvinces.getJSONObject(i);
                Province province = new Province();
                province.setProvinceName(provinceObject.getString("name"));
                province.setProvinceCode(provinceObject.getInt("id"));
                province.save();
            }
            return true;
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    return false;
}

    /**
     * 解析和处理服务器返回的市级的数据
     */
    public static boolean handleCitiesResponse(String response,int provinceId){
        if (!TextUtils.isEmpty(response)){
            try {
                JSONArray allCities = new JSONArray(response);
                for (int i = 0; i < allCities.length() ; i++) {
                    JSONObject cityObject = allCities.getJSONObject(i);
                    City city = new City();
                    city.setCityName(cityObject.getString("name"));
                    city.setCityCode(cityObject.getInt("id"));
                    city.setProvinceId(provinceId);
                    city.save();

                }
                return true;
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
        return false;
    }
    /**
     * 解析和处理服务器返回的县级的数据
     */
    public static boolean handleCountyResponse(String response,int cityId){
        if (!TextUtils.isEmpty(response)){
            try {
                JSONArray allCounties = new JSONArray(response);
                for (int i = 0; i < allCounties.length() ; i++) {
                    JSONObject countryObject = allCounties.getJSONObject(i);
                    County country = new County();
                    country.setCountyName(countryObject.getString("name"));
                    country.setWeatherId(countryObject.getString("weather_id"));
                    country.setCityId(cityId);
                    country .save();
                }
                return true;
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
        return false;
    }


}

 HttpTool :

package com.example.okhttpdemo;

import okhttp3.OkHttpClient;
import okhttp3.Request;

public class HttpTool {
    /**
     *
     * @param address 接口地址URL
     * @param callback
     */
    public static void sendOkhttpRequest(String address,okhttp3.Callback callback){
        // 1、创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient();
        // 2、创建Request对象
        Request request = new Request.Builder().url(address).build();
        // 3、发送异步请求
        client.newCall(request).enqueue(callback);
    }
}

Province : 

package com.example.okhttpdemo.Bean;

import org.litepal.crud.LitePalSupport;

public class Province extends LitePalSupport {
    private int id;
    private String provinceName;
    private int provinceCode;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getProvinceName() {
        return provinceName;
    }

    public void setProvinceName(String provinceName) {
        this.provinceName = provinceName;
    }

    public int getProvinceCode() {
        return provinceCode;
    }

    public void setProvinceCode(int provinceCode) {
        this.provinceCode = provinceCode;
    }
}

 City:

package com.example.okhttpdemo.Bean;

import org.litepal.crud.LitePalSupport;

public class City extends LitePalSupport {
    private int id;
    private String cityName;
    private int cityCode;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public int getCityCode() {
        return cityCode;
    }

    public void setCityCode(int cityCode) {
        this.cityCode = cityCode;
    }

    public int getProvinceId() {
        return provinceId;
    }

    public void setProvinceId(int provinceId) {
        this.provinceId = provinceId;
    }

    private int provinceId;

}

County : 

package com.example.okhttpdemo.Bean;

import org.litepal.crud.LitePalSupport;

public class County extends LitePalSupport {
    private  int id;
    private String countyName;
    private String weatherId;
    private int cityId;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCountyName() {
        return countyName;
    }

    public void setCountyName(String countyName) {
        this.countyName = countyName;
    }

    public String getWeatherId() {
        return weatherId;
    }

    public void setWeatherId(String weatherId) {
        this.weatherId = weatherId;
    }

    public int getCityId() {
        return cityId;
    }

    public void setCityId(int cityId) {
        this.cityId = cityId;
    }
}

activity_main: 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#7283DD"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/teal_200">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/title_text"
            android:layout_centerInParent="true"
            android:textColor="#fff"
            android:textSize="20sp"/>
        <Button
            android:id="@+id/back_button"
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_marginLeft="10dp"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:background="@drawable/back"
            />
    </RelativeLayout>
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


</LinearLayout>

litepal.xml: 

<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <dbname value = "okhttpdemo"/>
    <version value = "1"/>
    <list>
        <mapping class = "com.example.okhttpdemo.Bean.Province"/>
        <mapping class = "com.example.okhttpdemo.Bean.City"/>
        <mapping class = "com.example.okhttpdemo.Bean.County"/>
    </list>
</litepal>

AndroidManifest: 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.okhttpdemo">
<uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:networkSecurityConfig="@xml/network_security_config"
        android:name = "org.litepal.LitePalApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.NoActionBar">
        <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>

依赖: 

  implementation("com.squareup.okhttp3:okhttp:3.4.1")
    implementation 'org.litepal.guolindev:core:3.2.3'
    implementation 'com.google.code.gson:gson:2.7'

运行结果:

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/870058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web 服务器 -【Tomcat】的简单学习

Tomcat1 简介1.1 什么是Web服务器 2 基本使用2.1 下载2.2 安装2.3 卸载2.4 启动2.5 关闭2.6 配置2.7 部署 3 Maven创建Web项目3.1 Web项目结构3.2 创建Maven Web项目 4 IDEA使用Tomcat4.1 集成本地Tomcat4.2 Tomcat Maven插件 Tomcat 1 简介 1.1 什么是Web服务器 Web服务器是…

【MySQL】并发执行事务可能存在的问题, 事务的四种隔离级别

文章目录 前言一、并发执行事务可能存在的问题1, 脏读问题2, 不可重复读3, 幻读 二、MySQL 的四种隔离级别1, READ UNCOMMITTED 读未提交2, READ COMMITTED 读已提交3, REPEATABLE READ 可重复读 (MySQL 的默认事务隔离级别)4, SERIALIZABLE 串行化 总结 前言 各位读者好, 我是…

Mac如何打开隐藏文件中Redis的配置文件redis.conf

Redis下载(通过⬇️博客下载的Redis默认路径为&#xff1a;/usr/local/etc) Redis下载 1.打开终端进入/usr文件夹 cd /usr 2.打开/local/文件夹 open local 3.找到redis.conf并打开,即可修改配置信息

MATLAB算法实战应用案例精讲-【图像处理】图像分类模型Swin TrasnformerViT

目录 Swin Trasnformer 1. 模型介绍 2. 模型结构 3. 模型实现 4. 模型特点 5. 模型效果 ViT( Vision Transformer) 模型介绍 模型结构与实现 1. 图像分块嵌入 2. 多头注意力 3. 多层感知机&#xff08;MLP&#xff09; 4. DropPath 5. 基础模块 6. 定义ViT网络 …

gulimall-缓存-缓存使用

文章目录 前言一、本地缓存与分布式缓存1.1 使用缓存1.2 本地缓存1.3 本地模式在分布式下的问题1.4 分布式缓存 二、整合redis测试2.1 引入依赖2.2 配置信息2.3 测试 三、改造三级分类业务3.1 代码改造 四、高并发下缓存失效问题4.1 缓存穿透4.2 缓存雪崩4.3 缓存击穿 五、分布…

零售行业供应链管理核心KPI指标(一) – 能力、速度、效率和成本

有关零售行业供应链管理KPI指标的综合性分享&#xff0c;涉及到供应链能力、速度、效率和成本总共九大指标&#xff0c;是一个大框架&#xff0c;比较核心也比较综合。 衡量消费品零售企业供应链管理效率和水平的核心KPI通常有哪些&#xff1f; 图片来源-派可数据&#xff08;…

OPENCV C++(十二)模板匹配

正常模板匹配函数 matchTemplate(img, templatee, resultMat, 0);//模板匹配 这里0代表的是方法&#xff0c;一般默认为0就ok img是输入图像 templatee是模板 resultmat是输出 1、cv::TM_SQDIFF&#xff1a;该方法使用平方差进行匹配&#xff0c;因此最佳的匹配结果在结果为…

【java】递归

java递归 递归的概念求135...19求阶乘 递归的概念 所谓的递归就是&#xff0c;方法调用自身&#xff0c;称之为递归方法 求135…19 public class Java16_Object_Recursion {public static void main(String[] args) {// 1 3 5 7 9... 19int result computeAP( 10 );Sys…

【移动机器人运动规划】04 ——轨迹生成

文章目录 前言相关代码整理: 介绍Minimum Snap OptimizationDifferential Flatness(微分平坦)Minimum-snapSmooth 1D TrajectorySmooth Multi-Segment TrajectoryOptimization-based Trajectory Generation Convex Optimization&#xff08;凸优化&#xff09;凸函数和凸集凸优…

第3章:线性模型

线性回归 优点&#xff1a;简单、基本、可理解性好。 适用于处理数值型数据。编码&#xff1a;序关系&#xff08;衣服号码s、m、l等等&#xff09;独热编码&#xff08;00010&#xff09; 求解 求偏导让导数为0&#xff1f;为什么&#xff1f; 希望找到极值点&#xff0c;即…

vector【1】介绍与使用(超详解哦)

vector 引言vector介绍接口使用默认成员函数迭代器容量元素访问数据修改 总结 引言 在string部分&#xff0c;我们详细的介绍了各个接口的使用&#xff0c;虽然其不属于STL的一部分&#xff0c;但是接口与STL中的容器相似&#xff0c;所以我们在学习使用vector等STL容器的使用…

最强自动化测试框架Playwright(7)- 使用cookie避免重复登录

playwright在称为浏览器上下文的隔离环境中执行测试。这种隔离模型提高了可重复性&#xff0c;并防止了级联测试失败。测试可以加载现有的经过身份验证的状态。这消除了在每次测试中进行身份验证的需要&#xff0c;并加快了测试执行速度。 每次测试前登录 以下示例登录到 Git…

工单管理系统有什么优点?工单系统是如何提高企业服务质量和运营效率的?

工单管理系统是一款基于云平台打造的高效报修工单管理系统&#xff0c;为企业报修管理、维保流程优化和后勤决策分析提供全面支持。通过应用工单管理系统&#xff0c;企业能够轻松提升报修效率&#xff0c;降低人工成本&#xff0c;同时提高后勤管理的质量和效益。系统利用先进…

【数据结构•堆】堆排序(理论基础)

堆的定义  • 堆是一个完全二叉树   –所有叶子在同一层或者两个连续层   –最后一层的结点占据尽量左的位置  • 堆性质   –为空, 或者最小元素在根上   –两棵子树也是堆 存储方式  • 最小堆的元素保存在heap[1..hs]内   – 根在heap[1]   –K的左儿子是2k,…

C++语法中bitset位图介绍及模拟实现

一、位图的引入 先来看下边一道面试题&#xff1a; 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。 经过我们之前的学习&#xff0c;我们可能会有以下的思路&#xff1a; 对这些数进行排序&#xff…

Openlayers实战:列表与图层双向信息提示

在Openlayers的实际项目中,经常会在左侧列出信息列表,右边的地图上显示的是对应的图层内容,两边是一一对应的,为了看出来选择的是哪一个,就需要两边互相提示,本示例就很好的展示了这种效果,具体的方法请参考源代码。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhu…

HICP学习--BGP综合小实验

一、实验拓扑 二、实验需求 1、R2-7每台路由器均存在一个环回接口用于建立邻居&#xff0c;同时还存在一个环回来代表连接用户的接口;最终这些连接用户的接口网络需要可以和R1/8的环回通讯 2、AS2网段地址172.16.0.0/16 减路由条目数量 三、实验步骤 首先配置IP R1配置 [r1]…

2023国赛数学建模D题思路分析

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 全国大学生数学建模…

拓扑布局和建立小型网络

练习 2.6.1&#xff1a;拓扑布局和建立小型网络 地址表 本实验不包括地址表。 拓扑图 学习目标 正确识别网络中使用的电缆物理连接点对点交换网络验证每个网络的基本连通性 简介&#xff1a; 许多网络问题都可以在网络的物理层解决。因此&#xff0c;必须清楚了解网络连接…

软件测试基础篇——LAMP环境搭建

LAMP 1、Linux系统的其他命令 find命令&#xff1a;在目录下查找文件 ​ 格式一&#xff1a;find 路径 参数 文件名 ​ 路径&#xff1a;如果没有指定路径&#xff0c;默认是在当前目录下 ​ 参数&#xff1a;-name 根据文件名来查找&#xff0c;区分大小写&#xff1b; -…