Android网络请求库的使用(okhttp、retrofit、rxjava)

2023-11-17

前置工作

首先新建项目,添加网络权限,这个权限不需要⽤户授权, 默认申请就给, 不添加的话会报错:
在这里插入图片描述
然后在gradle中添加一下依赖:

dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.1'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.20'
}

okhttp的基本使用

MainActivity.java文件大致如下:

package com.example.okhttpuse;

//导入的包,此处略
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "okhttpuse";
    private final OkHttpClient client = new OkHttpClient();
    private TextView tvContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.btn_test).setOnClickListener(this);
        tvContent = findViewById(R.id.tv_content);
    }

    @Override
    public void onClick(View v) {
        okhttpPostDemo();   //此处填入要测试的方法
    }
	void okhttpDemo(){
        //见下文
    }
    void okhttpAsyncDemo(){   //相比于同步的写法,这样的写法无需我们自己再写一个Thread,okhttp会帮我们把请求放到异步中去执行
        //见下文
    }

    void okhttpParams(){     //对于get请求   拼接请求参数
		//见下文
    }
    void okhttpPostDemo(){
        //见下文
    }
}

okhttp第一个demo

void okhttpDemo(){
        Request request = new Request.Builder().url("https://reqres.in/api/users?page=2").build();
        tvContent.setText("请求中......");

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response response = client.newCall(request).execute();
                    Log.d(TAG,"okhttpdemo:" + response.body().string());
                    runOnUiThread(new Runnable() {  //更新UI不能在⼦线程当中, 必须在主线程当中或UI线程当中
                        @Override
                        public void run() {
                            tvContent.setText("请求返回的状态码为:" + response.code());
                        }
                    });
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
    }

需要注意的点:

  1. 由于网络请求不能放在主线程中,所以我们新开一个线程去发送网络请求
  2. 由于更新UI不能放在子线程当中,只能在主线程中或UI线程中,所以我们把更新UI卸载UI线程中

okhttp的异步写法,更常见

void okhttpAsyncDemo(){   //相比于同步的写法,这样的写法无需我们自己再写一个Thread,okhttp会帮我们把请求放到异步中去执行
        Request request = new Request.Builder().url("https://reqres.in/api/users?page=2").build();
        tvContent.setText("请求中......");

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {   //请求失败的情况下走这个回调
                Log.d(TAG, "onFailure:请求失败");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {   //请求成功的情况下走这个回调
                Log.d(TAG, "onResponse:" + response.body().string());
                runOnUiThread(new Runnable() {  //更新UI不能在⼦线程当中
                    @Override
                    public void run() {
                        tvContent.setText("请求返回的状态码为:" + response.code());
                    }
                });
            }
        });
    }

GET请求中使用okhttp拼接参数

void okhttpParams(){     //对于get请求   拼接请求参数
    HttpUrl.Builder builder = HttpUrl.parse("https://reqres.in/api/users").newBuilder();
    builder.addQueryParameter("page","2");
    String url = builder.build().toString();
    Log.d(TAG, "okhttpParams: " + url);
}

okhttp发起POST请求

void okhttpPostDemo(){
    RequestBody body = new FormBody.Builder()
            .add("name","yuanrenxue")
            .add("job","developer")
            .build();

    Request request = new Request.Builder().url("https://reqres.in/api/users")
            .post(body).build();

    tvContent.setText("请求中......");
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
            Log.d(TAG, "onFailure:请求失败");
        }

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
            Log.d(TAG, "onResponse:" + response.body().string());
            runOnUiThread(new Runnable() {  //更新UI不能在⼦线程当中, 必须在主线程当中
                @Override
                public void run() {
                    tvContent.setText("请求返回的状态码为:" + response.code());
                }
            });
        }
    });
}

拦截器第一个demo,打印请求的时间

首先新建一个类:LoggingInterceptor

package com.example.okhttpuse;
//导包略过
public class LoggingInterceptor implements Interceptor {

    private static final String TAG = "yuanrenxue";

    @NotNull
    @Override
    public Response intercept(@NotNull Chain chain) throws IOException {
        Request request = chain.request();
        long t1 = System.nanoTime();
        Response response = chain.proceed(request);
        long t2 = System.nanoTime();
        Log.d(TAG, "intercept: " + (t2 - t1));
        return response;
    }
}

在这里插入图片描述
测试结果:
在这里插入图片描述

retrofit的基本使用

retrofit:对okhttp3进⾏了⼀个封装, 是⼀个类型安全的http客户端,我们可以指定请求参数的类型,也可以指定返回值的类型,对于返回值我们可以直接解析成一个java对象。

retrofit第一个demo:GET请求

主要用法:
新建一个Interface:

public interface ApiService {
    @GET("api/users")  //具体请求的URL以及请求方式:GET请求
    Call<PageResponseBean> listUsers(@Query("page") Integer page);  //<PageResponseBean>:直接把返回的数据json序列化成为java中的对象
           //listUsers:具体请求的名字   //(@Query("page") Integer page):具体请求的参数,参数为page,类型为Integer
}

再新建一个PageResponseBean类:

public class PageResponseBean {
    @SerializedName("page")  //需要把哪一个字段进行序列化,对应json中的key
    Integer page;
    @SerializedName("total_pages")
    Integer totalPages;
}

主要方法如下:

void retrofitGetDemo(){
    tvContent.setText("请求中...");
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://reqres.in")   
            .addConverterFactory(GsonConverterFactory.create())  //把服务端返回的json字符串转化成java中的对象
            .build();

    retrofit.create(ApiService.class).listUsers(2).enqueue(new retrofit2.Callback<PageResponseBean>() {
        @Override
        public void onResponse(retrofit2.Call<PageResponseBean> call, retrofit2.Response<PageResponseBean> response) {
            Log.d(TAG, "onResponse: " + response.body().page);
            tvContent.setText("请求的状态码为:" + response.code());
        }

        @Override
        public void onFailure(retrofit2.Call<PageResponseBean> call, Throwable t) {

        }
    });
}

和普通的okhttp相比,retrofit对okhttp进行了封装,这里并没有显式地去调用url,免去了我们手动切换ui线程。

retrofit发送post请求

对ApiService进行修改:

public interface ApiService {
    @GET("api/users")  //具体请求的URL以及请求方式:GET请求
    Call<PageResponseBean> listUsers(@Query("page") Integer page);  //<PageResponseBean>:直接把返回的数据json序列化成为java中的对象
    //listUsers:具体请求的名字   //(@Query("page") Integer page):具体请求的参数,参数为page,类型为Integer

    @POST("api/users")
    @FormUrlEncoded   //进行url编码,直接写的话可能会出现问题
    Call<UserBean> createUser(@Field("name") String name,@Field("job") String job );
}

新建一个UserBean类:

public class UserBean {
    @SerializedName("name")
    String name;
}

主要方法如下:

void retrofitPostDemo(){
    tvContent.setText("请求中...");
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://reqres.in")
            .addConverterFactory(GsonConverterFactory.create())  //把服务端返回的json字符串转化成java中的对象
            .build();

    retrofit.create(ApiService.class).createUser("yuanrenxue","developer").enqueue(new retrofit2.Callback<UserBean>() {
        @Override
        public void onResponse(retrofit2.Call<UserBean> call, retrofit2.Response<UserBean> response) {
            Log.d(TAG, "onResponse: " + response.body().name);
            tvContent.setText("请求的状态码为:" + response.code());
        }

        @Override
        public void onFailure(retrofit2.Call<UserBean> call, Throwable t) {

        }
    });
}

测试结果:
在这里插入图片描述

rxjava的基本使用

rxjava:响应式编程的库, 结合retrofit的使⽤。

第一个demo:GET请求

对ApiService进行修改:

@GET("api/users")
Observable<PageResponseBean> rxlistUsers(@Query("page") Integer page);

主要方法如下:

void rxJavaGetDemo(){

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://reqres.in")
            .addConverterFactory(GsonConverterFactory.create())  //把服务端返回的json字符串转化成java中的对象
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();

    retrofit.create(ApiService.class).rxlistUsers(2)
            .subscribeOn(Schedulers.io())   //把具体请求放到子线程中(异步线程)
            .observeOn(AndroidSchedulers.mainThread())   //将下面的subscribe的东西放到UI线程
            .subscribe(new Observer<PageResponseBean>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {
                    tvContent.setText("请求中...");
                }
                @Override
                public void onNext(@NonNull PageResponseBean pageResponseBean) {
                    Log.d(TAG, "onNext: " + pageResponseBean.totalPages);   //打印总的页数
                }
                @Override
                public void onError(@NonNull Throwable e) {
                    e.printStackTrace();
                }
                @Override
                public void onComplete() {
                    tvContent.setText("请求完成!");
                }
            });
}

发送POST请求

对ApiService进行修改:

@POST("api/users")
@FormUrlEncoded   //进行url编码,直接写的话可能会出现问题
Observable<UserBean> rxCreateUser(@Field("name") String name,@Field("job") String job );

主要方法如下:

void rxJavaPostDemo(){
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://reqres.in")
            .addConverterFactory(GsonConverterFactory.create())  //把服务端返回的json字符串转化成java中的对象
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();

    retrofit.create(ApiService.class).rxCreateUser("yuanrenxue","developer")
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<UserBean>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {
                    tvContent.setText("请求中...");
                }

                @Override
                public void onNext(@NonNull UserBean userBean) {
                    tvContent.setText("用户创建成功:" + userBean.name);
                }

                @Override
                public void onError(@NonNull Throwable e) {
                    e.printStackTrace();
                }

                @Override
                public void onComplete() {
                    //tvContent.setText("请求完成!");
                }
            });
}

一个较为复杂的Android请求案例,综合应用

主要逻辑:

  1. 获取⽤户列表
  2. 显示⽤户列表⽤户总个数
  3. 创建新⽤户
  4. 显示创建的⽤户的名字
  5. 登录
  6. 显示登录的token
  7. 获取单个⽤户信息
  8. 显示⽤户的头像

PageResponseBean:

public class PageResponseBean {
    @SerializedName("page")  //需要把哪一个字段进行序列化,对应json中的key
    Integer page;

    @SerializedName("total_pages")
    Integer totalPages;

    @SerializedName("total")
    Integer total;
}

UserBean:

public class UserBean {
    @SerializedName("name")
    String name;

    @SerializedName("avatar")
    String avatar;
}

新建一个UserDetailBean类

public class UserDetailBean {
    @SerializedName("data")
    UserBean data;
}

新建一个LoginBean类

public class LoginBean {
    @SerializedName("token")
    String token;
}

ApiService:

public interface ApiService {
    @GET("api/users")  //具体请求的URL以及请求方式:GET请求
    Call<PageResponseBean> listUsers(@Query("page") Integer page);  //<PageResponseBean>:直接把返回的数据json序列化成为java中的对象
    //listUsers:具体请求的名字   //(@Query("page") Integer page):具体请求的参数,参数为page,类型为Integer
    @POST("api/users")
    @FormUrlEncoded   //进行url编码,直接写的话可能会出现问题
    Call<UserBean> createUser(@Field("name") String name,@Field("job") String job );

    @GET("api/users")
    Observable<PageResponseBean> rxlistUsers(@Query("page") Integer page);

    @POST("api/users")
    @FormUrlEncoded   //进行url编码,直接写的话可能会出现问题
    Observable<UserBean> rxCreateUser(@Field("name") String name,@Field("job") String job );

    @POST("api/users")
    @FormUrlEncoded
    Observable<LoginBean> login(@Field("email") String email,@Field("password") String password);

    @GET("api/users/{userId}")  //只有路径参数
    Observable<UserDetailBean> rxUserInfo(@Path("userId") Integer userId);

    //图片请求的url,如https://reqres.in/img/faces/2-image.jpg
    @GET("img/faces/{path}")
    Observable<ResponseBody> getAvatar(@Path("path") String path);
}

以下是主要代码

void finalDemo(){
        //首先创建一个retrofit对象
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://reqres.in")
                .addConverterFactory(GsonConverterFactory.create())  //把服务端返回的json字符串转化成java中的对象
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        //获取用户列表
        retrofit.create(ApiService.class).rxlistUsers(2)
                .subscribeOn(Schedulers.io())    //把网络请求切换到异步线程
                .observeOn(AndroidSchedulers.mainThread())   //把对界面的修改内容,也就是请求返回的内容,切换到主线程
                .doOnNext(new Consumer<PageResponseBean>() {
                    @Override
                    public void accept(PageResponseBean pageResponseBean) throws Exception {
                        tvContent.setText("总人数为:" + pageResponseBean.total);   // 显示用户列表总个数:total
                    }
                })
                .observeOn(Schedulers.io())   //再次切换到异步线程
                .flatMap(new Function<PageResponseBean, ObservableSource<UserBean>>() {
                    @Override
                    public ObservableSource<UserBean> apply(@NonNull PageResponseBean pageResponseBean) throws Exception {
                        return retrofit.create(ApiService.class).rxCreateUser("yuanrenxue","developer");
                    }
                })  //创建一个新的用户
                .observeOn(AndroidSchedulers.mainThread())    //切换回主线程
                .doOnNext(new Consumer<UserBean>() {
                    @Override
                    public void accept(UserBean userBean) throws Exception {
                        tvContent.setText("当前用户名字:" + UserBean.class);
                    }
                })   //显示当前的用户名
                .observeOn(Schedulers.io())
                .flatMap(new Function<UserBean, ObservableSource<LoginBean>>() {
                    @Override
                    public ObservableSource<LoginBean> apply(@NonNull UserBean userBean) throws Exception {
                        return retrofit.create(ApiService.class).login("hhhh@163.com","asd12356");
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<LoginBean>() {
                    @Override
                    public void accept(LoginBean loginBean) throws Exception {
                        tvContent.setText("当前的用户token是:" + loginBean.token);
                    }
                })  //登录获取用户token并且显示出来
                .observeOn(Schedulers.io())
                .flatMap(new Function<LoginBean, ObservableSource<UserDetailBean>>() {
                    @Override
                    public ObservableSource<UserDetailBean> apply(@NonNull LoginBean loginBean) throws Exception {
                        return retrofit.create(ApiService.class).rxUserInfo(2);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .flatMap(new Function<UserDetailBean, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(@NonNull UserDetailBean userDetailBean) throws Exception {
                        return Observable.just(userDetailBean.data.avatar);
                    }
                })  //返回用户头像的地址
                .observeOn(Schedulers.io())
                .flatMap(new Function<String, ObservableSource<ResponseBody>>() {
                    @Override
                    public ObservableSource<ResponseBody> apply(@NonNull String s) throws Exception {
                        String[] paths = s.split("/");
                        String path = paths[paths.length-1];
                        return retrofit.create(ApiService.class).getAvatar(path);
                    }
                })
                .map(new Function<ResponseBody, Bitmap>() {
                    @Override
                    public Bitmap apply(@NonNull ResponseBody responseBody) throws Exception {
                        return BitmapFactory.decodeStream(responseBody.byteStream());
                    }
                })  //获取用户头像,转换成为Bitmap
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Bitmap>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        tvContent.setText("请求中...");
                    }
                    @Override
                    public void onNext(@NonNull Bitmap bitmap) {
                        ivAvatar.setImageBitmap(bitmap);
                    }
                    @Override
                    public void onError(@NonNull Throwable e) {

                    }
                    @Override
                    public void onComplete() {
                    }
                })
        ;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android网络请求库的使用(okhttp、retrofit、rxjava) 的相关文章

  • 如何快速自动发送FCM或APNS消息?

    我正在开发一项后端服务 通过 FCM 或 APNS 向移动应用程序发送推送通知 我想创建一个可以在一分钟内运行的自动化测试 并验证服务器是否可以成功发送通知 请注意 我不一定需要检查通知是否已送达 只需检查 FCM 或 APNS 是否已成功
  • Android - 从资产中解析巨大(超大)JSON 文件的最佳方法

    我正在尝试从资产文件夹中解析一些巨大的 JSON 文件 我如何加载并添加到 RecyclerView 我想知道解析这种大文件 大约 6MB 的最佳方法是什么 以及您是否知道可以帮助我处理此文件的良好 API 我建议您使用GSON lib h
  • SearchView过滤ListView

    我已经实现了搜索视图来过滤我的列表视图项目 当我输入任何文本时 它会过滤列表 但当我退出搜索视图时 它不会返回原始列表项 public class PlacesListAdapter extends ArrayAdapter
  • 谷歌坐标认证

    当我尝试连接到 Google 坐标时 总是出现异常GoogleAuthException 我拥有 Google 地图协调中心许可证 我确实使用我的包应用程序名称和 SHA1 在 google 控制台中创建了我的客户端 ID 我将权限添加到清
  • 当文本输入聚焦在 React Native for Android 的底部工作表上时,视图移出屏幕

    我正在使用图书馆 https github com osdnk react native reanimated bottom sheet https github com osdnk react native reanimated bott
  • Android 中 Kotlin 协程的正确使用方式

    我正在尝试使用异步更新适配器内的列表 我可以看到有太多的样板 这是使用 Kotlin 协程的正确方法吗 这个可以进一步优化吗 fun loadListOfMediaInAsync async CommonPool try Long runn
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • 你的CPU不支持NX

    我刚刚下载了 android studio 但是我遇到了一个问题 当我运行它时 它说你的 cpu 不支持 NX 我应该怎么办 NX 或实际上是 NX 处理器位 是处理器的一项功能 有助于保护您的 PC 免受恶意软件的攻击 当此功能未启用并且
  • 如何使用 IF 检查 TextView 可见性

    我有一个 onCheckedChangeListener 来根据选择的单选按钮显示文本视图 我有 1 个疑问和 1 个难题 想知道是否有人可以帮助我 问题 您能否将单选组默认检查值设置为 否 单选按钮 以便一开始就不会检查任何内容 问题 如
  • Ubuntu 16.04 - Genymotion:找不到 /dev/hw_random

    I install Genymotion on the Ubuntu 16 04 64Bit I created a virtual emulator for Android 6 0 then I run this emulator but
  • 在 SQLite 中搜索时排除 HTML 标签和一些 UNICODE 字符

    更新 4 我已经成功运行了firstchar例如 但现在的问题是使用regex 即使包含头文件 它也无法识别regex操作员 有什么线索可以解决这个问题吗 更新 2 我已经编译了sqlite3我的项目中的库 我现在正在寻找任何人帮助我为我的
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • 如何默认在 ActionOpenDocument 意图中显示“内部存储”选项

    我需要用户选择一个自定义文件类型的文件 并将其从 Windows 文件资源管理器拖到 Android 设备上 但默认情况下内部存储选项不可用 当我使用以下命令启动意图时 var libraryIntent new Intent Intent
  • Android访问远程SQL数据库

    我可以直接从 Android 程序访问远程 SQL 数据库 在网络服务器上 吗 即简单地打开包含所有必需参数的连接 然后执行 SQL 查询 这是一个私人程序 不对公众开放 仅在指定的手机上可用 因此我不担心第三方获得数据库访问权限 如果是这
  • 我的设备突然没有显示在“Android 设备选择器”中

    我正在使用我的三星 Galaxy3 设备来测试过去两个月的应用程序 它运行良好 但从今天早上开始 当我将设备连接到系统时 它突然没有显示在 Android 设备选择器 窗口中 我检查过 USB 调试模式仅在我的设备中处于选中状态 谁能猜出问
  • .isProviderEnabled(LocationManager.NETWORK_PROVIDER) 在 Android 中始终为 true

    我不知道为什么 但我的变量isNetowrkEnabled总是返回 true 我的设备上是否启用互联网并不重要 这是我的GPSTracker class public class GPSTracker extends Service imp
  • 一次显示两条Toast消息?

    我希望在一个位置显示一条 Toast 消息 并在另一位置同时显示另一条 Toast 消息 多个 Toast 消息似乎总是按顺序排队和显示 是否可以同时显示两条消息 是否有一种解决方法至少可以提供这种外观并且不涉及扰乱活动布局 Edit 看来
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 将 Intent 包装在 LabeledIntent 中以用于显示目的

    要求 我的应用程序中有一个 共享 按钮 我需要通过 Facebook 分享 我需要选择是否安装原生 Facebook 应用程序 我们的决定是 如果未安装该应用程序 则将用户发送到 facebook com 进行分享 当前状态 我可以检测何时
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • 【linux kernel】挂载根文件系统之rootfs

    挂载根文件系统之rootfs 文章目录 挂载根文件系统之rootfs 一 开篇 二 rootfs根文件系统 2 1 初始化rootfs 2 2 挂载rootfs文件系统 2 3 创建简单的rootfs根文件系统目录和文件 2 4 打开0 1
  • [Python系列-27]:命令行解析器argparse详解

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122276305 目录 第1章 arg
  • GB/T28181-2022相对2016版“基于TCP协议的视音频媒体传输要求“规范解读和技术实现

    规范解读 GB T28181 2022和GB T28181 2016规范 有这么一条 更改了附录 D 基于 TCP 协议的视音频媒体传输要求 见附录 D 2016 年版的附录 L 本文主要是针对GB T28181 2022里面提到的 基于
  • 【Java】Excel中添加下拉框

    0 两种方式 有两种方式可以实现 我仅在此记录一下 POI Hutool 1 使用 POI import org apache poi ss usermodel DataValidation import org apache poi ss
  • Web自动化元素定位

    元素定位就是通过元素的信息或元素层级结构来定位元素 要使用Web自动化操作元素 必须首先找到此元素 1 元素定位方式 1 1 基于元素属性特有的定位方式 1 id element driver find element by id id i
  • Python入门习题(91)——OpenJudge百练习题:汉诺塔问题

    OpenJudge百练第4147号习题 汉诺塔问题 题目描述 解题思路 参考答案 测试用例 小结 题目描述 来源 OpenJudge网站 百练习题集 第4147号习题 要求 总时间限制 1000ms 内存限制 65536kB 描述 一 汉诺
  • 猎聘发布《2019年中国5G人才需求大数据报告》

    在今年2月于西班牙巴塞罗那举办的2019世界移动通信大会上 华为 小米 vivo等中国企业先后扎堆发布了自己的5G手机 更加凸现了本次大会 5G商用产品 这一亮点 与此同时 5G成为大众新的关注焦点 借此契机 中高端人才职业发展平台猎聘推出
  • OVAL学习笔记

    很多其它好文章 http blog csdn net aap159951 article details 51131937 OVAL由MITRE公司开发 是一种用来定义检查项 脆弱点等技术细节的一种描写叙述语言 OVAL相同使用标准的XML
  • Android图片设置点击事件,Android EditText中插入图片并响应点击事件

    import android os Bundle import android app Activity import android content Context import android util Log import andro
  • 第3章 R语言编程基础——基于R软件的传统计算(超详细)

    3 1 统计分析 多元统计分析常用的 R 包和函数 3 1 1 多元回归分析 随机误差 计量模型 案例分析 M2 的建模与预测 残差的五数 估计参数的回归值 标准差 t检验量 p value 单变量显著性检验 拟合优度和 F 检验 Resi
  • bnu1331 赈灾捐款 C语言版

    北京师范大学珠海分校 Judge Online of ACM ICPC 1331 赈灾捐款 C语言版 include
  • ubuntu18.04下的mysql创建表

    ubuntu18 04下的mysql创建表 MySQL创建数据表 错误排查 出现报错 百度的解决思路 实际操作 MySQL创建数据表 删除表 drop table h data 创建表 CREATE TABLE IF NOT EXISTS
  • 第9章、图像按钮ImageButton(从零开始学Android)

    在Android App应用中 默认的Button按钮尽管我们可以通过样式变成圆角 但有时感觉仍然不够美观 我们可以通过采用图像按钮ImageButton改善这种现状 今天我们就一起学习一下图像按钮的使用 知识点 图像按钮ImageButt
  • 【数据结构课设】 浮点数计算器

    一 简介 1 功能介绍 实数的计算 支持取对数 幂次 开方及加减乘除运算 2 模块设计 1 菜单界面 2 计算器功能简介 3 计算器功能实现 3 计算器功能实现方法 1 字符串读入用户的表达式 2 处理字符串 包括提取实数以及中缀转后缀 维
  • idea开发中git合并的代码,

    方法一 将master主分支 合并到 子分支dev上 1 当前如果在dev分支上 先提交dev分支的代码到本地 然后推送到服务器 2 然后切换分支到master主分支上 先更新master主分支的代码到本地 然后主分支就是最新代码了 3 再
  • python 安卓模拟点击_Android后台模拟点击探索(附源码)

    工作中我们需要自制一套工具 其中遇到需要模拟点击事件的需求 类似按键精灵的功能 支持后台持续运行 满足触发条件时完成点击 经过一番探索 一共整理出两种不同的方案 AccessibilityService 和 adb shell命令 读者可自
  • Matlab中的c2d函数离散化

    把传递函数离散化 dsys c2d sys ts method 传函离散 num den tfdata dsys v 离散后提取分子分母 这里面的method有好多种 zoh 零阶保持 假设控制输入在采样周期内为常值 为默认值 foh 一阶
  • 【自动化测试】——robotframework实战(一)搭建环境

    一 前提准备 python 3 9 6 pip 下载 最新版本 setuptools 下载 最新版本 二 下载robotframework框架 管理员模式打开cmd 下载RF pip install robotframework 3 1 下
  • tomcat 配置域名

    Tomcat 配置域名 在windows中 首先找到conf下面的server xml 把Connector 标签中的端口改成80 然后把添加一个Host name为域名appBase为路径 如下 Engine 标签也是 最后在C盘 win
  • Android网络请求库的使用(okhttp、retrofit、rxjava)

    Android网络请求库的使用 前置工作 okhttp的基本使用 okhttp第一个demo okhttp的异步写法 更常见 GET请求中使用okhttp拼接参数 okhttp发起POST请求 拦截器第一个demo 打印请求的时间 retr