Android入门第55天-在Android里使用OKHttp组件访问网络资源

news/2024/5/21 4:50:13/文章来源:https://blog.csdn.net/lifetragedy/article/details/128424733

简介

今天的课程开始进入高级课程类了,我们要开始接触网络协议、设备等领域编程了。在今天的课程里我们会使用OKHttp组件来访问网络资源而不是使用Android自带的URLConnection。一个是OKHttp组件更方便二个是OKHttp组件本身就带有异步回调功能。

下面就进入课程。

课程目标

我们的课程目标有4个点:

  1. 使用OKHttp组件;
  2. 使用OKHttp组件加载网络图片显示在APP的ImgView里;
  3. 使用OKHttp组件加载给定网页代码显示在ScrollView里;
  4. 使用OKHttp组件加载给定网页显示在WebView里;

以上过程都为异步加载。

代码前在gradle里要先声明对于OKHttp组件的引用

要使用OKHttp组件,我们必须要在build.gradle中加入以下语句:

implementation 'com.squareup.okhttp3:okhttp:3.10.0'

 以下是加完上述语句后的build.gradle。

 访问网络资源需要给到APP以权限

我们因为要访问网络资源,因此我们需要给到APP以相应的权限。编辑AndroidManifest.xml文件,并加入以下两行声明。

    <uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WAKE_LOCK" />

 加完后的AndroidManifest.xml长这样

 代码

菜单res\menu\pop_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><item android:id="@+id/menuItemDisplayPic" android:title="加载图片" /><item android:id="@+id/menuItemDisplayHtmlCode" android:title="加载网页代码" /><item android:id="@+id/menuItemDisplayHtmlPage" android:title="加载网页" />
</menu>

主UI界面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><Buttonandroid:id="@+id/buttonShowMenu"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/textColor"android:layout_centerHorizontal="true"android:layout_marginTop="10dp"android:text="展示弹出菜单" /><ImageViewandroid:id="@+id/imgPic"android:layout_width="match_parent"android:layout_height="match_parent"android:visibility="gone" /><ScrollViewandroid:id="@+id/scroll"android:layout_width="match_parent"android:layout_height="match_parent"android:visibility="gone"><TextViewandroid:id="@+id/htmlTxt"android:layout_width="wrap_content"android:layout_height="wrap_content" /></ScrollView><WebViewandroid:id="@+id/webView"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

MainActivity

package org.mk.android.demo.http;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.ScrollView;
import android.widget.TextView;import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import okhttp3.OkHttpClient;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
public class MainActivity extends AppCompatActivity {private String TAG = "DemoOkHttp";private Button buttonShowMenu;private TextView htmlTxt;private ImageView imgPic;private WebView webView;private ScrollView scroll;private Bitmap bitmap;private String htmlContents;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);buttonShowMenu = (Button) findViewById(R.id.buttonShowMenu);htmlTxt = (TextView) findViewById(R.id.htmlTxt);imgPic = (ImageView) findViewById(R.id.imgPic);webView = (WebView) findViewById(R.id.webView);scroll = (ScrollView) findViewById(R.id.scroll);buttonShowMenu.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {PopupMenu popup = new PopupMenu(MainActivity.this, buttonShowMenu);popup.getMenuInflater().inflate(R.menu.pop_menu, popup.getMenu());popup.setOnMenuItemClickListener(new MenuItemClick());popup.show();}});}// 定义一个隐藏所有控件的方法:private void hideAllWidget() {imgPic.setVisibility(View.GONE);scroll.setVisibility(View.GONE);webView.setVisibility(View.GONE);}private class MenuItemClick implements PopupMenu.OnMenuItemClickListener {@Overridepublic boolean onMenuItemClick(MenuItem item) {String imgPath = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.alicdn.com%2Fi2%2F2542318073%2FO1CN01fJvTi029VTwR16EvP_%21%212542318073.jpg&refer=http%3A%2F%2Fimg.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1673938156&t=69e5ee87fbf4b81b5f6eea53ed5b5158";String htmlPagePath = "https://www.baidu.com";switch (item.getItemId()) {case R.id.menuItemDisplayPic:downLoadImgFromPath(imgPath);break;case R.id.menuItemDisplayHtmlCode:getHtmlAsync(htmlPagePath, 102);break;case R.id.menuItemDisplayHtmlPage:getHtmlAsync(htmlPagePath, 103);break;}return true;}}private Handler httpHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(@NonNull Message msg) {Log.i(TAG, ">>>>>>receive handler Message msg.what is: " + msg.what);switch (msg.what) {case 101:hideAllWidget();imgPic.setVisibility(View.VISIBLE);Log.i(TAG, "begin to show img from bitmap type's data");imgPic.setImageBitmap(bitmap);break;case 102:hideAllWidget();Log.i(TAG, "begin to show html contents");scroll.setVisibility(View.VISIBLE);Log.d(TAG, ">>>>>>htmlContents->\n" + htmlContents);htmlTxt.setText(htmlContents);break;case 103:hideAllWidget();Log.i(TAG, "begin to show html page in webview");webView.setVisibility(View.VISIBLE);Log.d(TAG, ">>>>>>htmlContents->\n" + htmlContents);webView.loadDataWithBaseURL("", htmlContents, "text/html", "UTF-8", "");break;}return false;}});/*** 使用okhttp 异步下载图片*/private void downLoadImgFromPath(String path) {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url(path).build();Log.i(TAG, ">>>>>>into doanloadImgFromPath method");try {Call call = client.newCall(request); // 使用client去请求call.enqueue(new Callback() { // 回调方法,>>> 可以获得请求结果信息InputStream inputStream = null;@Overridepublic void onFailure(Call call, IOException e) {Log.e(TAG, ">>>>>>下载失败", e);}@Overridepublic void onResponse(Call call, Response response) throws IOException {Log.i(TAG, ">>>>>>into onResponse method");try {inputStream = response.body().byteStream();Log.i(TAG, ">>>>>>the response code is: " + response.code());if (200 == response.code()) {bitmap = BitmapFactory.decodeStream(inputStream);Log.i(TAG, ">>>>>>sendEmptyMessage 101 to handler");httpHandler.sendEmptyMessage(101);} else {Log.i(TAG, ">>>>>>下载失败");}} catch (Exception e) {Log.e(TAG, ">>>>>>okHttp onResponse error: " + e.getMessage(), e);} finally {try {inputStream.close();} catch (Exception e) {}}}});} catch (Exception e) {Log.e(TAG, ">>>>>>OkHttp调用失败", e);}}//异步不需要创建线程private void getHtmlAsync(String path, int handlerCode) {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url(path).build();//请求的call对象Call call = client.newCall(request);//异步请求call.enqueue(new Callback() {//失败的请求@Overridepublic void onFailure(@NonNull Call call, @NonNull IOException e) {Log.e(TAG, ">>>>>>加载path失败", e);}//结束的回调@Overridepublic void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {//响应码可能是404也可能是200都会走这个方法Log.i(TAG, ">>>>>>the response code is: " + response.code());if (200 == response.code()) {try {ResponseBody responseBody = response.body();BufferedSource source = responseBody.source();source.request(Long.MAX_VALUE);Buffer buffer = source.buffer();Charset UTF8 = Charset.forName("UTF-8");htmlContents = buffer.clone().readString(UTF8);Log.i(TAG, ">>>>>>sendEmptyMessage " + handlerCode + " to handler");httpHandler.sendEmptyMessage(handlerCode);Log.i(TAG, "getAsyncHtmlGet成功");} catch (Exception e) {Log.e(TAG, ">>>>>>read htmlPage error: " + e.getMessage(), e);}}}});}
}

核心代码导读

我们使用的是

Call call = client.newCall(request);

它本身就是支持异步的一个调用。 然后在得到相应的Http报文后使用一个Handler向APP主界面发起改变界面中内容的调用。

这边有一点需要注意的是OKHttp在返回的response.body()这个API,在一次请求里只能被使用一次。即如果你已经有以下一句类似的调用:

inputStream = response.body().byteStream();

你就不能再在它以下的语句中调用一次response.body()了。

自己动一下手试试看效果吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_616829.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(Java)车厢重组

车厢重组一、题目描述二、输入格式三、输出格式四、样例&#xff08;1&#xff09;样例输入&#xff08;2&#xff09;样例输出五、正确代码六、思路一、题目描述 在一个旧式的火车站旁边有一座桥&#xff0c;其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最…

Fragment案例

Fragment案例 1.案例要求 框架布局项目难点&#xff1a;1 导航栏的实现&#xff0c;显示导航按钮、切换Fragment 2 每个Fragment的创建、显示 3 Fragment的跳转&#xff08;从新闻列表到新闻详情&#xff0c;再返回&#xff09; 涉及的技术&#xff1a;用RadioGroup及RadioButt…

【源码共读】Vite 项目自动添加 eslint 和 prettier

vite-pretty-lint库是一个为Vite创建的Vue或React项目初始化eslint和prettier的库。 该库的目的是为了让开发者在创建项目时&#xff0c;不需要手动配置eslint和prettier&#xff0c;而是通过vite-pretty-lint库来自动配置。 源码地址&#xff1a; vite-pretty-lintgithub1s…

3ds Max:标准几何体

三维软件中一般有许多非常复杂的命令&#xff0c;能够完成非常复杂的图形运算&#xff0c;但其实许多绚丽的图形也是由最基本的几何体构成&#xff0c;许多复杂的命令也是基本的运算程序的集合&#xff0c;就像是砖块&#xff0c;构成了复杂的大厦。任何一个几何体&#xff0c;…

【Linux】缓冲区/磁盘inode/动静态库制作

目录 一、缓冲区 1、缓冲区的概念 2、缓冲区的意义 3、缓冲区刷新策略 4、同一份代码&#xff0c;打印结果不同 5、仿写FILE 5.1myFILE.h 5.2myFILE.c 5.3main.c 6、内核缓冲区 二、了解磁盘 1、磁盘的物理结构 2、磁盘的存储结构 2.1磁盘的定位 3、磁盘的抽象…

Sentinel系列——概述与安装1-1

Sentinel系列——概述与安装1-1概述服务雪崩解决方法基本概念资源规则Sentinel 是如何工作的安装Sentinel下载地址启动修改sentinel启动参数设置启动端口设置用户名密码概述 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言…

java开发的环保网站垃圾分类系统源码

本项目是基于springboot开发的小区垃圾分类的监管系统。为了更好的督促小区业主更好的进行垃圾分类和垃圾投放&#xff0c;本系统设计了一套积分奖罚机制&#xff0c;如果业主此次投放垃圾符合分类要求则加10积分&#xff0c;不符合则扣除200积分&#xff0c;积分不够需要进行扫…

Zookeeper 4 Zookeeper JavaAPI 操作 4.1 Curator 介绍 4.2 Curator API 常用操作【建立连接】

Zookeeper 【黑马程序员Zookeeper视频教程&#xff0c;快速入门zookeeper技术】 文章目录Zookeeper4 Zookeeper JavaAPI 操作4.1 Curator 介绍4.1.1 Curator 介绍4.2 Curator API 常用操作4.2.1 Curator API 常用操作4.2.2 建立连接4 Zookeeper JavaAPI 操作 4.1 Curator 介绍…

spring提前加载,懒加载,bean的作用域和注入注解讲解

前言 sping知识随笔笔记&#xff1b;spring提前加载&#xff0c;懒加载&#xff0c;bean的作用域和注入注解讲解 这里写目录标题前言1 depends-on2 bean的作用域3 lazy-init 懒加载4 Autowrite和Resource的区别和使用1 depends-on depends-on 是提前加载&#xff0c;比如在实…

《北京市数字经济促进条例》图解来了

《北京市数字经济促进条例》 2023/1/1 二十大对建设数字经济作出重要部署。党的二十大报告中指出&#xff0c;“加快建设网络强国、数字中国”、“加快发展数字经济&#xff0c;促进数字经济和实体经济深度融合&#xff0c;打造具有国际竞争力的数字产业集群”。习总书记强调…

eclipse和sts安装lombok

eclipse和sts安装lombok 说明 sts 是 eclipse集成springboot的开发环境 所以 sts 和 eclipse 安装 lombok 步骤基本一样 参考网址: https://blog.csdn.net/qq_39826207/article/details/119007580?ops_request_misc%257B%2522request%255Fid%2522%253A%252216708973141680…

生物系转行学编程,如今身家26亿

在编程界有许多明星级别的大牛&#xff0c;他们有些人学习成绩很差&#xff0c;有些人甚至不是科班出身&#xff0c;但对编程的狂热和努力&#xff0c;成就了他们在IT界“名利双收”的地位。 在我们中国编程界就有这样一位大牛&#xff0c;非科班出身&#xff0c;却做到了神一般…

注册中心Nacos

Nacos是Spring Cloud Alibaba提供的一个软件 这个软件主要具有注册中心和配置中心(课程最后讲解)的功能 我们先学习它注册中心的功能 微服务中所有项目都必须注册到注册中心才能成为微服务的一部分 注册中心和企业中的人力资源管理部门有相似 当前微服务项目中所有的模块,在…

Qt中实例化一个函数变量时加不加括号的区别,以及括号中的this的使用

一、设计一个测试小程序 废话不多说&#xff0c;直接上代码。 main.h函数就不多说了&#xff0c;没改动。直接上mainwindow.h&#xff0c;也没改动。看mainwindow.cpp的内容。 #include "mainwindow.h" #include "ui_mainwindow.h" #include "test.…

网友:我30多岁了,现在转行学编程来得及吗?

这些年&#xff0c;互联网行业的变化发展很快&#xff0c;很多公司也是借助互联网发展的大趋势发展的非常好。 水涨船高&#xff0c;行业好&#xff0c;意味着互联网行业的从业者的工资也就跟着高&#xff0c;很多互联网行业刚入门的月薪基本都已经过万了&#xff0c;一些传统行…

Web入门开发【二】- 网站设计

欢迎来到霍大侠的小院&#xff0c;我们来学习Web入门开发的系列课程。 首先我们来了解下这个课程能学到什么&#xff1f; 1、你将可以掌握Web网站的开发全过程。 2、了解基础的HTML&#xff0c;CSS&#xff0c;JavaScript语言。 3、开发自己的第一个网站。 4、认识很多对编…

计算机网络基础——一文详解IPv4与子网划分

IPv4地址概述 在因特网中&#xff0c;为了实现计算机之间的相互通信&#xff0c;通常需要为每台计算机分配一个IP地址。在互联网的发展过程中主要有两个版本的互联网协议&#xff0c;分别是IPv4(Internet Protocol version4)和IPv6 (Internet Protocol version 6) IPv4的IP地址…

javaSE(包、封装、static用法、代码块)

1.包 &#xff08;文件夹&#xff09; 为了更好的管理类&#xff0c;把多个类收集在一起成为一组&#xff0c;称为软件包。 在Java中也引入了包&#xff0c;包是对类、接口等的封装机制的体现&#xff0c;是一种对类或者接口等的很好的组织方式&#xff0c;比如&#xff1a;一…

UG NX二次开发(C#)-获取模型文件的预览图片

文章目录 1.前言2. 模型文件预览图介绍3.采用二次开发的方法获取模型的预览图4.验证1.前言 UG NX保持的prt文件中保存了模型的预览位图,但是采用UG NX二次开发时不能直接提取出来,本文讲解一下将prt文件的预览位图提取出来并单独保存。 2. 模型文件预览图介绍 如果我们在UG…

词义分析和词义消歧

Synsets(“synonym sets”, effectively senses) are the basic unit of organization in WordNet.同义词集 对于许多应用程序&#xff0c;我们希望消除歧义 • 我们可能只对一种含义感兴趣 • 在网络上搜索chemical plant 化工厂&#xff0c;我们不想搜到香蕉中的化学物质 所以…