Android 三方库okhttp、gson、glide的使用

okhttp

Okhttp是网络请求框架。OkHttp主要有Get请求、Post请求等功能。
使用前,需要添加依赖,在当前项目的build.gradle下加入以下代码:

implementation 'com.squareup.okhttp3:okhttp:3.5.0' 
Okhttp的Get请求

使用OkHttp进行Get请求只需要完成以下四步:

  1. 获取OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
  1. 构造Request对象
Request request = new Request.Builder()
                .get()
                .url("https://v0.yiketianqi.com/api?version=v62&appid=12646748&appsecret=SLB1jIr8&city=北京")
                .build();
  1. 将Request封装为Call
Call call = okHttpClient.newCall(request);
  1. 根据需要调用同步或者异步请求方法
//同步调用,返回Response,会抛出IO异常
Response response = call.execute();
 
//异步调用,并设置回调函数
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Toast.makeText(OkHttpActivity.this, "get failed", Toast.LENGTH_SHORT).show();
    }
 
    @Override
    public void onResponse(Call call, final Response response) throws IOException {
        final String res = response.body().string();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText(res);
            }
        });
    }
});


OkHttp进行Post请求

使用OkHttp进行Post请求和进行Get请求很类似,只需要以下五步:

  1. 获取OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
  1. 构建FormBody或RequestBody或构架我们自己的RequestBody,传入参数
//OkHttp进行Post请求提交键值对
FormBody formBody = new FormBody.Builder()
                .add("username", "admin")
                .add("password", "admin")
                .build();
                
//OkHttp进行Post请求提交字符串
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"), "{username:admin;password:admin}");

//OkHttp进行Post请求上传文件
File file = new File(Environment.getExternalStorageDirectory(), "1.png");
if (!file.exists()){
    Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
}else{
    RequestBody requestBody2 = RequestBody.create(MediaType.parse("application/octet-stream"), file);
}

//OkHttp进行Post请求提交表单
File file = new File(Environment.getExternalStorageDirectory(), "1.png");
if (!file.exists()){
    Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
    return;
}
RequestBody muiltipartBody = new MultipartBody.Builder()
        //一定要设置这句
        .setType(MultipartBody.FORM)
        .addFormDataPart("username", "admin")//
        .addFormDataPart("password", "admin")//
        .addFormDataPart("myfile", "1.png", RequestBody.create(MediaType.parse("application/octet-stream"), file))
        .build();
  1. 构建Request,将FormBody作为Post方法的参数传入
final Request request = new Request.Builder()
                .url("http://www.jianshu.com/")
                .post(formBody)
                .build();
  1. 将Request封装为Call
Call call = okHttpClient.newCall(request);
  1. 调用请求,重写回调方法
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Toast.makeText(OkHttpActivity.this, "Post Failed", Toast.LENGTH_SHORT).show();
    }
 
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        final String res = response.body().string();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText(res);
            }
        });
    }
});

gson

GSON在解析json的时候,大体上有2种类型,一种是直接在内存中生成object或array,通过手工指定key来获取值;另一种是借助javabean来进行映射获取值。
使用Gson需要添加依赖,在当前项目的build.gradle下加入以下代码:

implementation 'com.google.code.gson:gson:2.8.6'

实例:解析天气预报api的json。
首先,需要新建一个实体类,eg:

public class CityWeather {
    private String city;
    private String country;
    private String week;
    private String wea;
    @SerializedName("wea_img")
    private String weaImg;
    private String tem;
    private String tem1;
    private String tem2;
    private String win;
    @SerializedName("win_speed")
    private String winSpeed;
    @SerializedName("win_meter")
    private String winMeter;
    @SerializedName("air_level")
    private String airLevel;
    @SerializedName("air_pm25")
    private String airPm25;
    @SerializedName("hours")
    private List<HourWeather> hours;

    public List<HourWeather> getHourWeatherList() {
        return hours;
    }

    public void setHourWeatherList(List<HourWeather> hourWeatherList) {
        this.hours = hourWeatherList;
    }

    public String getWeaImg() {
        return weaImg;
    }

    public void setWeaImg(String weaImg) {
        this.weaImg = weaImg;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getWeek() {
        return week;
    }

    public void setWeek(String week) {
        this.week = week;
    }

    public String getWea() {
        return wea;
    }

    public void setWea(String wea) {
        this.wea = wea;
    }

    public String getTem() {
        return tem;
    }

    public void setTem(String tem) {
        this.tem = tem;
    }

    public String getTem1() {
        return tem1;
    }

    public void setTem1(String tem1) {
        this.tem1 = tem1;
    }

    public String getTem2() {
        return tem2;
    }

    public void setTem2(String tem2) {
        this.tem2 = tem2;
    }

    public String getWin() {
        return win;
    }

    public void setWin(String win) {
        this.win = win;
    }

    public String getWinSpeed() {
        return winSpeed;
    }

    public void setWinSpeed(String winSpeed) {
        this.winSpeed = winSpeed;
    }

    public String getWinMeter() {
        return winMeter;
    }

    public void setWinMeter(String winMeter) {
        this.winMeter = winMeter;
    }

    public String getAirLevel() {
        return airLevel;
    }

    public void setAirLevel(String airLevel) {
        this.airLevel = airLevel;
    }

    public String getAirPm25() {
        return airPm25;
    }

    public void setAirPm25(String airPm25) {
        this.airPm25 = airPm25;
    }

}

其次,需要新建一个用于json解析的类

public class WeatherUtil {
    public static CityWeather getCityWeather(String str) {
        Gson gson = new Gson();
        Type listType = new TypeToken<CityWeather>(){}.getType();
        CityWeather cityWeather = gson.fromJson(str, listType);
        return cityWeather;
    }
}

最后,结合okhttp即可解析网络获取的json:

public class WeatherActivity extends AppCompatActivity {
    private List<HourWeather> hourWeatherList;
    private TextView mWeather;
    private TextView mCity;
    private TextView mTem;
    private TextView mAirLevel;
    private TextView mTem1;
    private TextView mTem2;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.weather_activity);
        initView();
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .get()
                .url("https://v0.yiketianqi.com/api?version=v62&appid=12646748&appsecret=SLB1jIr8&city=北京")
                .build();
        Call call = okHttpClient.newCall(request);

        //异步调用,并设置回调函数
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Toast.makeText(WeatherActivity.this, "get failed", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                final String res = response.body().string();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        CityWeather cityWeather = WeatherUtil.getCityWeather(res);
                        mWeather.setText(cityWeather.getWea());
                        mCity.setText(cityWeather.getCity());
                        mTem.setText(cityWeather.getTem());
                        mAirLevel.setText(cityWeather.getAirLevel());
                        mTem1.setText(cityWeather.getTem1());
                        mTem2.setText(cityWeather.getTem2() + "℃");
                        hourWeatherList = cityWeather.getHourWeatherList();

                        int resID = getResources().getIdentifier(cityWeather.getWeaImg() + "_bg" , "mipmap", getPackageName());
                        Glide.with(WeatherActivity.this)
                                .asBitmap()
                                .load(resID)
                                .into(new SimpleTarget<Bitmap>(){
                                    @Override
                                    public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
                                        Drawable drawable = new BitmapDrawable(resource);
                                        mConstraintLayout.setBackground(drawable);
                                    }
                                });
                    }
                });
            }
        });
    }

    private void initView() {
        mWeather = findViewById(R.id.weather);
        mCity = findViewById(R.id.city);
        mTem = findViewById(R.id.tem);
        mAirLevel = findViewById(R.id.air_level);
        mTem1 = findViewById(R.id.tem1);
        mTem2 = findViewById(R.id.tem2);
    }
}

glide

Glide 是一个图片加载库,跟它同类型的库还有 Picasso、Fresco、Universal-Image-Loader 等。
glide库的优点:

  • 加载类型多样化:Glide 支持 Gif、WebP 等格式的图片。
  • 生命周期的绑定:图片请求与页面生命周期绑定,避免内存泄漏。
  • 使用简单(链式调用),且提供丰富的 Api 功能 (如: 图片裁剪等功能)。
  • 高效的缓存策略:
  1. 支持多种缓存策略 (Memory 和 Disk 图片缓存)。
  2. 根据 ImageView 的大小来加载相应大小的图片尺寸。
  3. 内存开销小,默认使用 RGB_565 格式 (3.x 版本)。
  4. 使用 BitmapPool 进行 Bitmap 的复用。

首先,使用glide需要添加依赖,在当前项目的build.gradle下加入以下代码:

implementation 'com.github.bumptech.glide:glide:4.8.0'

其次,在加载图片时,若需要网络请求或者本地内存的访问,需要在当前项目的AndroidManifest.xml中加入请求权限代码:

    //用于网络请求
    <uses-permission android:name="android.permission.INTERNET"/>
    //它可以监听用户的连接状态并在用户重新连接到网络时重启之前失败的请求
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    //用于硬盘缓存和读取
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
glide的使用
        Glide.with(MainActivity)
                .load(R.mipmap.image)
                .into(imageView);
  • with()方法可以接收Context、Activity或者Fragment类型的参数。
  • load()方法中不仅可以传入图片地址,还可以传入图片文件File,resource,图片的byte数组等。
  • into()参数可以直接写图片控件,如需要给其他控件添加背景图片,则需要:
.into(new SimpleTarget<Bitmap>(){
                                    @Override
                                    public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
                                        Drawable drawable = new BitmapDrawable(resource);
                                        mConstraintLayout.setBackground(drawable);
                                    }
                                });

加载本地图片:

File file = new File(getExternalCacheDir() + "/image.jpg");
Glide.with(this).load(file).into(imageView);

加载应用资源:

int resource = R.drawable.image;
Glide.with(this).load(resource).into(imageView);

加载二进制流:

byte[] image = getImageBytes();
Glide.with(this).load(image).into(imageView);

加载Uri对象:

Uri imageUri = getImageUri();
Glide.with(this).load(imageUri).into(imageView);

注意with()方法中传入的实例会决定Glide加载图片的生命周期,如果传入的是Activity或者Fragment的实例,那么当这个Activity或Fragment被销毁的时候,图片加载也会停止。如果传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会停止。
取消图片:Glide.with(this).load(url).clear();

你可能感兴趣的:(android,java)