目录
1 配置网络协议
2 请求流程
3 代码编写
4 Gson解析JSON
4.1 引入依赖
5 优化网络请求数据
5.1 OkHttp
5.2 Retrofit
5.2.1 引入依赖
1 配置网络协议
网络编程第一件事就是: 配置网络协议
2 请求流程 3 代码编写这里先铺垫一些基础知识:
查询数据库,网络请求等都是耗时的 *** 作。
生命周期方法 -> 自动调用 -> 主线程(UI线程) -> 不能执行耗时的 *** 作(读文件,网络请求) onResume onCreate 这些都是生命周期方法
1、那如果有耗时的 *** 作,我们不在主线程,那该怎么办? 再创建一个线程就好了! 2、所有的UI *** 作必须在主线程中执行(设置textView中的内容等...)
public class MainActivity extends AppCompatActivity {
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text1);
Thread thread = new Thread(){
@Override
public void run() {
super.run();
try {
/*
//http://121.4.44.56/user
//http://121.4.44.56/object1
//http://121.4.44.56/object2
//http://121.4.44.56/object3
*/
URL url = new URL("http://121.4.44.56/object3");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
InputStream inputStream = urlConnection.getInputStream();
Reader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
String result = "";
String temp;
while((temp = bufferedReader.readLine())!=null){
result += temp;
}
Log.i("gls",result);
String finalResult = result;
// 在UI线程运行
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONObject jsonObject = new JSONObject(finalResult);
// 1、获取JSON字段
// String name = jsonObject.getString("name");
// textView.setText(name);
// 2、JSON中嵌套JSON
// JSONObject classObject = jsonObject.getJSONObject("class");
// String classname = classObject.getString("classname");
// textView.setText(classname);
// 3、JSON的字段中含有数组(字符串数组)
// JSONArray jsonArray = jsonObject.getJSONArray("students");
// for (int i = 0;i{
});
bufferedReader.close();
reader.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
}
}
4 Gson解析JSON
4.1 引入依赖
implementation 'com.google.code.gson:gson:2.9.0'
// lambda 表达式
runOnUiThread(()->{
// 利用第三方框架,一次性将JSON解析为对象
Gson gson = new Gson();
Student student = gson.fromJson(finalResult,Student.class);
textView.setText(student.getName());
});
package com.hnucm.network;
import com.google.gson.annotations.SerializedName;
public class Student {
private int age;
private String name;
private boolean isstudent;
// JSON中有个字段名为class,但class是关键字。可以通过这种串行名的方式解决该问题
// 该注解的功能: class1 相当于 JSON 中的 class
@SerializedName("class")
public MyClass class1;
public class MyClass{
public String grade;
public String classname;
}
// get/set等方法此处省略不写,但需要,望周知.
}
虽然省略了对JSON的解析,但需要写一个类。其实写类的过程也是挺麻烦的.
但现在市面上已经有一个插件,可以再次简化类的编写!
就自动生成了代码
public class Student {
public String grade;
public String classname;
public List students;
public static class StudentsDTO {
public String id;
public int age;
public String name;
public boolean isstudent;
}
}
5 优化网络请求数据
此前的网络请求数据是用的原生Java代码写的,比较麻烦,而且还没有对请求数据异常进行处理,所以,要对网络请求数据的方式进行优化。
5.1 OkHttpOkHttp是第三方框架,用来简化网络的数据请求。
但该框架还是有些不足之处:返回的数据还是在子线程中,设置TextView还要手动转化到UI线程;还需要使用Gson转Json到对应的实体类,还是比较繁琐的。所以还有一个框架:Retrofit
5.2 RetrofitRetorfit是对OkHttp框架的再次封装,使得对网络数据请求更加的简单。这里就不具体介绍OkHttp,而更加注重对最终框架Retrofit的使用。
5.2.1 引入依赖// 解析JSON 第三发框架
implementation 'com.google.code.gson:gson:2.9.0'
// OkHttp 简化网络请求 -- 第三方框架
implementation("com.squareup.okhttp3:okhttp:4.9.3")
// Retrofit 框架
// implementation("com.squareup.okhttp3:okhttp:4.9.3") 上面已包含
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// 日志拦截
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
注意点:
OkHttp3和retrofit2两个包中都有Call这个类,所以我们一定要导入正确的包名。
package com.hnucm.network2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class WeatherTest extends AppCompatActivity {
// https://market.aliyun.com/products/57096001/cmapi010812.html# 阿里云天气预报查询
//https://www.fastmock.site/#/project/3da12455e6a72de6b5827a737400be04 fastmock
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_weather_test);
TextView textView = findViewById(R.id.textView);
Api api = RetrofitUtils.getRetrofit("https://ali-weather.showapi.com/").create(Api.class);
String appCode = "APPCODE " + "具体个人的appCode";
Call weatherCall = api.getWeather(appCode,"长沙"); // 注意不要导错包
weatherCall.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
WeatherResult weatherResult = response.body();
String result = weatherResult.getShowapi_res_body().getNow().getWeather()
+ " 气温 "
+ weatherResult.getShowapi_res_body().getNow().getTemperature();
textView.setText(result);
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
}
这里面使用到了一个自己写好的工具类去获得retrofit (工具类的作用:简化代码编写,复用)
RetrofitUtils.getRetrofit
工具类:
package com.hnucm.network2;
import android.util.Log;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitUtils {
public static Retrofit getRetrofit(String url) {
//日志显示级别
HttpLoggingInterceptor.Level level= HttpLoggingInterceptor.Level.BODY;
//新建log拦截器
HttpLoggingInterceptor loggingInterceptor=new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.d("RetrofitMessage","OkHttp====Message:"+message);
}
});
loggingInterceptor.setLevel(level);
//定制OkHttp
OkHttpClient.Builder httpClientBuilder = new OkHttpClient
.Builder();
//OkHttp进行添加拦截器loggingInterceptor
httpClientBuilder.addInterceptor(loggingInterceptor);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.client( httpClientBuilder.build())
.build();
return retrofit;
}
}
Api接口代码:
package com.hnucm.network2;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Query;
public interface Api {
// http://121.4.44.56/object
@GET("object") // get请求
Call getStudent();
//https://ali-weather.showapi.com/area-to-weather
@GET("area-to-weather")
Call getWeather(@Header("Authorization") String appCode, @Query("area") String area);
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)