Okhttp是网络请求框架。OkHttp主要有Get请求、Post请求等功能。
使用前,需要添加依赖,在当前项目的build.gradle下加入以下代码:
implementation 'com.squareup.okhttp3:okhttp:3.5.0'
使用OkHttp进行Get请求只需要完成以下四步:
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);
//同步调用,返回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请求和进行Get请求很类似,只需要以下五步:
OkHttpClient okHttpClient = new OkHttpClient();
//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();
final Request request = new Request.Builder()
.url("http://www.jianshu.com/")
.post(formBody)
.build();
Call call = okHttpClient.newCall(request);
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在解析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 是一个图片加载库,跟它同类型的库还有 Picasso、Fresco、Universal-Image-Loader 等。
glide库的优点:
首先,使用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.with(MainActivity)
.load(R.mipmap.image)
.into(imageView);
.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();