Android Volley 基本使用

Android Volley 基本使用

本篇主要介绍 Google 给Android 平台提供的 Volley 一个 Http请求库 , 齐射!

1.概述

Volley是Google 提供的一个小巧的异步请求库,扩展很强支持okhttp,(默认是 Android2.3 及以上基于 HttpURLConnection,2.3 以下基于 HttpClient 实现), Volley 英文齐射的意思 就是指无数急促的请求,适合数据量小,并且通信频繁的场景

在这里插入图片描述

2.准备工作

想通过 volley 调用一个我自己的博客文章接口 然后展示标题 和 短描述 到 页面上

2.1 编写布局文件

上面展示标题 下面展示 短描述

image-20221224011336283

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/showTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textStyle="bold"
        android:textSize="25sp"
        android:textColor="@color/black"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.2" />

    <TextView
        android:id="@+id/showShortDesc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/showTitle"
        app:layout_constraintVertical_bias="0.2" />


</androidx.constraintlayout.widget.ConstraintLayout>

2.2 提供博客接口地址
#随便找了我的一篇博客的 请求地址
https://www.askajohnny.com/blogs/blogInfo/303/15

2.3 通过JSON To Kotlin Class 插件生成 data class (kotlin)

和 IDEA 中 Json Formatter插件类似,它是生成JAVA的, 而这个 JSON To Kotlin Class 插件是用来生成kotlin 的数据类的

右击文件 Generate… 或者 control + 回车 唤起转化窗口

image-20221223173306949

package com.johnny.volleydemo

data class BlogInfo(
    val code: Int,
    val `data`: Data,
    val msg: String
)

data class Data(
    val anchors: List<Anchor>,
    val blogContent: String,
    val blogImageUrl: String,
    val blogMdContent: String,
    val blogShortContent: String,
    val blogTitle: String,
    val blogTypeAnchor: Any,
    val blogTypeId: String,
    val blogTypeName: Any,
    val clickCount: Int,
    val createDate: String,
    val createMonth: Any,
    val createTime: String,
    val createUser: Any,
    val id: Int,
    val isThumbed: String,
    val nextBlogId: Any,
    val nextBlogTitle: Any,
    val previousBlogId: Any,
    val previousBlogTitle: Any,
    val thumbCount: Int,
    val updateTime: String
)

data class Anchor(
    val anchorId: String,
    val anchorName: String
)

3.引入依赖

根据你的dsl 语言 选择适合的方式引入依赖

Groovy

dependencies {
    implementation 'com.android.volley:volley:1.2.1'
}

Kotlin

dependencies {
    implementation("com.android.volley:volley:1.2.1")
}

4.发送请求

使用 volley 需要先构建一个请求, 并且把请求提交到 newRequestQueue 队列中, 提交后 volley 会根据构建的请求异步发送请求, 只需要在回调的地方处理请求的响应即可

4.1 StringRequest 构建请求

volley 提供了 StringRequest 构建请求

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val titleTextView = findViewById<TextView>(R.id.showTitle)
        val shortDescTextView = findViewById<TextView>(R.id.showShortDesc)

        //使用 volley需要创建一个Queue
        val requestQueue = Volley.newRequestQueue(this)
        //请求的 博客 url
        val url =
            "https://www.askajohnny.com/blogs/blogInfo/303/15"
        //构建StringRequest请求
        val stringRequest = StringRequest(Request.Method.GET,
            url, {
                //由于我后端没有在header 的 charset中返回 UTF-8 所以默认当做ISO-8859-1格式
                //所以这里需要先转化成 UTF-8
                val data = String(
                    it.toByteArray(Charsets.ISO_8859_1),
                    Charsets.UTF_8
                )
                Log.d(TAG, "onCreate: stringRequest  ${data}")
                //通过Gson转化 成上面生成的 数据类
                val blogInfo = Gson().fromJson(data, BlogInfo::class.java)
                //把后端返回的数据 展示在 textview上
                titleTextView.text = blogInfo.data.blogTitle
                shortDescTextView.text = blogInfo.data.blogShortContent
            }, {
                Log.d(TAG, "onCreate: stringRequest error ${it.message}")
            })
        //把请求推入 queue 会自动进行异步请求
        requestQueue.add(stringRequest)
    }

效果如下…

image-20221224012424698

4.2 JsonObjectRequest 构建请求

按照 JSONObject 获取数据

第二个参数 null 表示Get请求 第二个参数如果有设置 则是post方式

GET 请求

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val titleTextView = findViewById<TextView>(R.id.showTitle)
        val shortDescTextView = findViewById<TextView>(R.id.showShortDesc)

        //val url = "https://weather.api.bdymkt.com/day?city=无锡"
        //
        val requestQueue = Volley.newRequestQueue(this)
        val url =
            "https://www.askajohnny.com/blogs/blogInfo/303/15"
        val postRequest = object : JsonObjectRequest(url, null,
            {
                Log.d(TAG, "volleyInitData: request success $it")
                titleTextView.text = it.getJSONObject("data").get("blogTitle") as String?
                shortDescTextView.text = it.getJSONObject("data").get("blogShortContent") as String
            }, {
                Log.d(TAG, "volleyInitData: request error ${it.message}")
            }) {
            override fun getHeaders(): MutableMap<String, String> {
                val headers = mutableMapOf<String, String>()
                headers["Accept"] = "application/json"
                headers["Content-Type"] = "application/json; charset=UTF-8"
                return headers
            }
        }
        requestQueue.add(postRequest)
    }

POST请求

此时 第二个参数设置了JSONObject() 是 post方式

        val jsonObject = JSONObject()
        jsonObject.put("pageNumber", 0)
        jsonObject.put("pageSize", 20)
        val jsonArray = JSONArray()
        jsonObject.put("ids", jsonArray)
				//此时 第二个参数设置了 是 post方式 
        val postRequest = object : JsonObjectRequest(requestUrl, jsonObject, {
            Log.d(TAG, "volleyInitData: jsonstr:$it")
            val jsonStr = it.toString()
            val blogInfo = Gson().fromJson(jsonStr, BlogInfo::class.java)
            blogAdapter.list
                .addAll(blogInfo.data.content)
            blogAdapter.notifyDataSetChanged()
        }, {
            Log.d(TAG, "volleyInitData: request error ${it.message}")
        }) {
            override fun getHeaders(): MutableMap<String, String> {
                val headers = mutableMapOf<String, String>()
                headers["Accept"] = "application/json";
                headers["Content-Type"] = "application/json; charset=UTF-8";
                return headers
            }
        }

5. 扩展

5.1 添加 Header 和 Params

注意 需要object: 进行匿名内部类, 重写 getHeaders getParams getPriority 等等方法

//注意 需要object: 进行匿名内部类,  重写 getHeaders  getParams 方法
val stringRequest = object : StringRequest(Request.Method.GET,
    url, {
        val data = String(
            it.toByteArray(Charsets.ISO_8859_1),
            Charsets.UTF_8
        )
        Log.d(TAG, "onCreate: stringRequest  ${data}")
        val blogInfo = Gson().fromJson(data, BlogInfo::class.java)
        titleTextView.text = blogInfo.data.blogTitle
        shortDescTextView.text = blogInfo.data.blogShortContent
    }, {
        Log.d(TAG, "onCreate: stringRequest error ${it.message}")
    }) { //最后面 大括号 里面是匿名内部类重新方法
    override fun getHeaders(): MutableMap<String, String> {
        //返回 map map里面添加 需要放入Header的数据
        return super.getHeaders()
    }

    override fun getParams(): MutableMap<String, String>? {
        //返回 map map里面添加 需要添加的 query params
        return super.getParams()
    }
     //指定 优先级
     override fun getPriority(): Priority {
        return Priority.HIGH
     }
}

5.2 取消队列中的请求

如果想把队列中的请求取消 , 需要给请求设置一个 tag , 然后调用队列的 cancelAll 可以把指定tag的请求取消了

 //...

 stringRequest.setTag("obj");
 queue.add(objRequest);
        //取消请求
 queue.cancelAll("obj");

总结

本篇主要介绍 andriod 中 Volley的基本使用方式,它是官方开发的一个HTTP框架 简化操作 , Volley 的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕

更多Android开发学习资料可以扫码免费领取!

高级Android插件化与组件化(含实战教程和源码)

扫描上方二维码

即可领取全套【Andorid插件化、组件化全套资料】啦!

《高级Android插件化强化实战(附源码)》

第一章 插件化技术的前世今生

​ ● 插件化提要

​ ● 插件化发展历史

img 第二章 插件化原理

​ ● 类加载

​ ● 双亲委托机制

​ ● 资源加载

​ ● 四大组件支持

​ ● ProxyActivity代理

​ ● hook方式

​ ● 其他组件

​ ● Android动态加载框架DL的架构与基本原理解析

​ ● Android 插件化框架 DynamicLoadApk 源码分析

img 第三章 Android插件化初探

​ ● 从零开始实现一个插件化框架

img 第四章 架构演化(大厂篇)

​ ● 360插件开发之DroidPlugin

​ ● 滴滴VirtualApk实战

​ ● 基于VirtualAPK Android重构之插件化

​ ● 爱奇艺插件化原理分析之 Neptune框架

​ ● 360开源全面插件化框架RePlugin 实战

​ ● 腾讯插件化框架 Shadow项目解析

img

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 Android Studio 实现天气预报的基本代码: 1. 首先,我们需要在 Android Studio 中创建一个新项目。在创建项目时,请确保选择“Empty Activity”作为初始活动。 2. 在 res/layout 文件夹中创建一个新的布局文件,命名为 activity_main.xml。在此布局文件中,我们将添加几个 TextView 和 EditText,以便用户输入城市名称并显示其天气预报。 3. 在 MainActivity.java 中,我们将使用 OpenWeatherMap API 来获取天气预报。请确保您已经在 openweathermap.org 上注册并获取了 API 密钥。 4. 在 MainActivity.java 中,添加以下代码来获取 API 数据: ``` private static String API_KEY = "YOUR_API_KEY"; private static String API_URL = "http://api.openweathermap.org/data/2.5/weather?q="; public void getWeatherData(String city) { String url = API_URL + city + "&appid=" + API_KEY; JsonObjectRequest jsonObjectRequest = new JsonObjectRequest (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { //处理 API 响应 } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { //处理错误响应 } }); //将请求添加到请求队列中 RequestQueue queue = Volley.newRequestQueue(this); queue.add(jsonObjectRequest); } ``` 5. 在 onResponse 方法中,我们将解析响应并从中提取所需的数据。以下是一个例子: ``` try { JSONObject mainObject = response.getJSONObject("main"); double temperature = mainObject.getDouble("temp"); double feelsLike = mainObject.getDouble("feels_like"); JSONObject weatherObject = response.getJSONArray("weather").getJSONObject(0); String description = weatherObject.getString("description"); //更新 UI TextView temperatureTextView = findViewById(R.id.temperature_textview); temperatureTextView.setText(temperature + "°C"); TextView feelsLikeTextView = findViewById(R.id.feels_like_textview); feelsLikeTextView.setText("Feels like " + feelsLike + "°C"); TextView descriptionTextView = findViewById(R.id.description_textview); descriptionTextView.setText(description); } catch (JSONException e) { e.printStackTrace(); } ``` 6. 最后,在 MainActivity.java 中,我们将在用户单击“获取天气”按钮时调用 getWeatherData 方法,并传递用户输入的城市名称。 ``` Button getWeatherButton = findViewById(R.id.get_weather_button); getWeatherButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EditText cityEditText = findViewById(R.id.city_edittext); String city = cityEditText.getText().toString(); getWeatherData(city); } }); ``` 这是一个简单的天气预报应用程序,您可以在此基础上进行扩展和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值