Android - NetWork

Android - NetWork,第1张

目录

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 OkHttp

OkHttp是第三方框架,用来简化网络的数据请求。

但该框架还是有些不足之处:返回的数据还是在子线程中,设置TextView还要手动转化到UI线程;还需要使用Gson转Json到对应的实体类,还是比较繁琐的。所以还有一个框架:Retrofit

5.2 Retrofit

Retorfit是对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);
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/795465.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存