Android入门(15)| 网络

文章目录

  • WebView
  • HTTP
    • 使用HttpURLConnection
    • 使用OkHttp
  • 封装网络操作
    • 封装HttpURLConnection
    • 封装OkHttp


WebView

WebView 可以在 应用程序中(而不是浏览器) 展示一些网页。

布局文件 web_layout.xml

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><WebViewandroid:id="@+id/web_view"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>

活动文件:

public class WebActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.web_layout);WebView webView = findViewById(R.id.web_view);// 使WebView支持JavaScript脚本webView.getSettings().setJavaScriptEnabled(true);// 用当前WebView显示网页而不是浏览器webView.setWebViewClient(new WebViewClient());webView.loadUrl("https://www.bilibili.com/");}
}

要在 Android 中使用网络技术是需要在 AndroidManifest.xml 中声明权限的:

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

运行结果:
在这里插入图片描述


HTTP

使用HttpURLConnection

布局文件 http_layout.xml

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/button_sendRequest"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="发送请求"/><ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/response_text"android:layout_width="match_parent"android:layout_height="wrap_content"/></ScrollView></LinearLayout>
  • ScrollView控件: 以滚动形式查看屏幕外的内容。
  • TextView控件: 用以显示服务器返回的数据。

活动文件:

public class HTTPActivity extends AppCompatActivity {private static final String TAG = "HTTPActivity";TextView responseText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.http_layout);Button button_sendRequest = findViewById(R.id.button_sendRequest);responseText = findViewById(R.id.response_text);button_sendRequest.setOnClickListener(v->{sendRequestWithHttpURLConnection();Log.e(TAG, "click over");});}private void sendRequestWithHttpURLConnection() {// 开启子线程来发起网络请求new Thread(new Runnable() {@Overridepublic void run() {HttpURLConnection connection = null;BufferedReader reader = null;try {URL url = new URL("https://www.csdn.net/");connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);InputStream in = connection.getInputStream();Log.e(TAG, "get in");// 下面对获取到的输入流进行读取reader = new BufferedReader(new InputStreamReader(in));StringBuilder response = new StringBuilder();String line;while((line = reader.readLine()) != null){response.append(line);}Log.e(TAG, "run: "+response.toString());// 安卓不允许在子线程中进行UI操作// 通过runOnUiThread切换为主线程,然后将结果显示到界面中runOnUiThread(new Runnable() {@Overridepublic void run() {responseText.setText(response.toString());}});} catch (Exception e) {e.printStackTrace();} finally {if(reader != null){try {reader.close();} catch (IOException e){e.printStackTrace();}}if(connection != null){connection.disconnect();}}}}).start();}
}

运行结果:
在这里插入图片描述


使用OkHttp

OkHttp项目在github上的主页地址

build.gradle (:app) 文件的 dependencies 中添加依赖:

	// define a BOM and its versionimplementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.3"))// define any required OkHttp artifacts without versionimplementation("com.squareup.okhttp3:okhttp")

活动文件:

public class HTTPActivity extends AppCompatActivity {private static final String TAG = "HTTPActivity";TextView responseText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.http_layout);Button button_sendRequest = findViewById(R.id.button_sendRequest);responseText = findViewById(R.id.response_text);button_sendRequest.setOnClickListener(v->{sendRequestWithOkHttp();Log.e(TAG, "click over");});}private void sendRequestWithOkHttp() {// 开启子线程来发起网络请求new Thread(new Runnable() {@Overridepublic void run() {try {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://www.bilibili.com").build();Log.e(TAG, "request: "+request);Response response = client.newCall(request).execute();Log.e(TAG, "response: "+response);String responseData = response.body().string();Log.e(TAG, "responseData: "+responseData);runOnUiThread(new Runnable() {@Overridepublic void run() {responseText.setText(responseData);}});} catch (IOException e) {e.printStackTrace();}}}).start();}
}

运行结果:
在这里插入图片描述


封装网络操作

封装HttpURLConnection

如果在每个使用到网络功能的地方都实现一遍发送HTTP请求的代码无疑是繁琐的。因此,不妨将常用的网络操作写成一个个静态方法,并将它们都存储在一个类中,如:

public class HttpUtil {private static final String TAG = "HttpUtil";public static String sendHttpRequest(String address){HttpURLConnection connection = null;try {URL url =new URL(address);connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);connection.setDoInput(true);connection.setDoOutput(true);InputStream in = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));StringBuilder response = new StringBuilder();String line;while((line = reader.readLine()) != null){response.append(line);}return response.toString();} catch (Exception e) {e.printStackTrace();return e.getMessage();} finally {if(connection != null){connection.disconnect();}}}
}

如此一来需要发送HTTP请求时即可如此实现:

String url = "https://www.bilibili.com";
String response = HttpUtil.sendHttpRequest(url);

但这仍有缺陷,sendHttpRequest() 方法内部并没有使用子线程,这意味着调用该方法时主线程有可能被阻塞,网络请求又是耗时操作,这对于运行效率而言无疑是种灾难。

而如果只是简单地在 sendHttpRequest() 方法中开启一个线程来发起HTTP请求,那么所有的耗时逻辑都是在子线程里进行的,sendHttpRequest() 方法会在 服务器还没来得及响应 的时候就执行结束了(子线程中的逻辑还没有执行完,主线程中已经结束了对sendHttpRequest() 方法的调用)。

因此应该配以回调机制来接受回馈数据,定义一个接口:

public interface HttpCallbackListener {// 成功响应时回调,参数为服务器返回的数据void onFinish(String response);// 操作错误时回调void onError(Exception e);
}

然后修改 HttpUtil.java

public class HttpUtil {private static final String TAG = "HttpUtil";public static void sendHttpRequest(final String address, HttpCallbackListener listener){new Thread(new Runnable() {@Overridepublic void run() {HttpURLConnection connection = null;try {URL url =new URL(address);connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);connection.setDoInput(true);connection.setDoOutput(true);InputStream in = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));StringBuilder response = new StringBuilder();String line;while((line = reader.readLine()) != null){response.append(line);}// 子线程中无法通过 return 返回数据,应通过 onFinish 方法回调if(listener != null){listener.onFinish(response.toString());Log.e(TAG, "run: "+response.toString());}} catch (Exception e) {if(listener != null){listener.onError(e);Log.e(TAG, "run: Exception");}} finally {if(connection != null){connection.disconnect();}}}}).start();}
}

此时我们调用 sendHttpRequest() 方法时需要将 HttpCallbackListener 的实例传入:

    private void sendRequestWithOkHttp() {// 开启子线程来发起网络请求new Thread(new Runnable() {@Overridepublic void run() {String url = "https://www.baidu.com";HttpUtil.sendHttpRequest(url, new HttpCallbackListener() {@Overridepublic void onFinish(String response) {runOnUiThread(new Runnable() {@Overridepublic void run() {responseText.setText(response);}});}@Overridepublic void onError(Exception e) {Log.e(TAG, "onError: "+e);}});}}).start();}

运行结果:
在这里插入图片描述


封装OkHttp

封装关于HTTP的操作:

public class HttpUtil {private static final String TAG = "HttpUtil";public static void sendHttpRequest(final String address, okhttp3.Callback callback){OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url(address).build();Log.e(TAG, "request: "+request);client.newCall(request).enqueue(callback);}
}

调用 HttpUtil.sendHttpRequest() 发送请求的方法:

    // 开启子线程来发起网络请求,OkHttpprivate void sendRequestWithOkHttp(){new Thread(new Runnable() {@Overridepublic void run() {HttpUtil.sendHttpRequest("https://www.bilibili.com", new okhttp3.Callback(){@Overridepublic void onResponse(Call call, Response response) throws IOException {String responseData = response.body().string();runOnUiThread(new Runnable() {@Overridepublic void run() {responseText.setText(responseData);}});}@Overridepublic void onFailure(Call call, IOException e) {Log.e(TAG, "onError: "+e);}});}}).start();}

PS: 不论是使用 HttpURLConnection 还是 OkHttp最终的回调接口都还是在子线程中,因此如果想要执行 UI 操作必须借助 runOnUiThread() 方法进行线程转换。

运行结果:
在这里插入图片描述

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

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

相关文章

Android入门(16)| 服务

文章目录概念Android 多线程继承 Thread继承 Runable 接口匿名类异步消息处理AsyncTask使用服务框架启动/停止服务绑定/解绑服务服务的生命周期前台服务IntentService完整版下载示例下载过程的回调接口&#xff1a;DownloadListener继承 AsyncTask 实现下载功能&#xff1a;Dow…

2020德勤面试开始了吗_2020国考面试开始,近期面试公告汇总,附结构化小组面试流程...

2020年国家公务员考试面试环节逐步恢复考试&#xff0c;各个招录部门已经发布面试考察公告&#xff0c;对于进入面试环节的国考考生来说&#xff0c;有必要了解近期国考面试的招录动态&#xff0c;提前做好面试准备。2020国考国家统计局机关面试面试确认&#xff1a;请进入面试…

项目积压需求项目计划_需求变更频繁,项目经理如何做好需求管理?

项目实施过程中&#xff0c;项目经理常常面临一个重大挑战——需求变更。需求变更无处不在&#xff0c;市场条件变化、新业务出现、战略目标调整、客户需求修改、资源限制等&#xff0c;都会造成需求变更。需求变更会影响项目的时间、成本和质量&#xff0c;对整个项目和团队成…

Android | Sensor.TYPE_ORIENTATION被废弃后的解决办法

文章目录概述getOrientation 方法根据 旋转矩阵R 获取 设备旋转弧度getRotationMatrix 方法根据 地磁场、加速度传感器对象 获取 旋转矩阵R代码参考资料概述 Sensor.TYPE_ORIENTATION 常数在 API 8 中已弃用&#xff0c;官方推荐使用 SensorManager.getOrientation() 替代。关…

【JAVA 开发小问题】 | String操作合集

文章目录截取特定两个字符之间的字符串截取特定两个字符之间的字符串 利用正则表达式&#xff0c;图片来源

uniapp 刷新后数据都没有了_环境温度传感器都没有连接,竟然还会有数据?

福田欧曼GTL(福康发动机、康明斯2880系统)匹配ECoffit尿素泵●故障现象&#xff1a;OBD故障灯点亮&#xff0c;不烧尿素&#xff0c;油耗高&#xff0c;动力不足●故障码&#xff1a;●维修分析&#xff1a;①故障指出加热器问题&#xff0c;摸下尿素箱温度&#xff0c;发现烫手…

保姆级教学!Xcode 配置 OpenGL 环境

文章目录GLFW获取 GLFWGLAD获取 GLAD在 Xcode 中配置下载好的 GLFW 和 GLAD配置流程检测是否配置成功无关配置的题外话——Xcode 下安全的删除移动操作GLFW Graphics Library Framework&#xff08;图形库框架&#xff09;&#xff0c;可以让我们通过其封装好的 通用API 来正确…

Android入门(17)| 百度提供的 Android定位SDK

文章目录配置百度提供的 Android定位SDK用于发布的 SHA1用于测试的 SHA1使用百度定位实例配置百度提供的 Android定位SDK 详情参见官方文档&#xff0c;这里仅对获取 SHA1 做详细介绍&#xff1a; 用于发布的 SHA1 用于测试的 SHA1 使用百度定位实例 public class LocationAc…

ios 不被遮挡 阴影_为何你没见到日环食?你不知道的天象常识原来还有这么多 | 返朴...

关注风云之声提升思维层次导读说好的日环食呢&#xff0c;为什么上周很多人只等到了日偏食?日食月食的时间和种类是怎么预测的?你真的弄懂了各种日食和月食的成因吗&#xff1f;你了解它们有什么区别和联系&#xff0c;又遵循什么样的时间规律吗? 日食和月食发生的频率一样吗…

初识贝塞尔(bezier)曲线

文章目录资料援引贝塞尔曲线的用途一阶贝塞尔&#xff08;bezier&#xff09;曲线二阶贝塞尔&#xff08;bezier&#xff09;曲线三阶贝塞尔&#xff08;bezier&#xff09;曲线高阶贝塞尔&#xff08;bezier&#xff09;曲线三阶贝塞尔曲线求插值&#xff08;Slerp&#xff09…

python代码测试 vim_用 Hypothesis 快速测试你的 Python 代码

点击上方“Python编程时光”&#xff0c;选择“加为星标”第一时间关注Python技术干货&#xff01;介绍无论你使用哪种编程语言或框架&#xff0c;测试都非常重要。Hypothesis是 Python 的一个高级测试库。它允许编写测试用例时参数化&#xff0c;然后生成使测试失败的简单易懂…

Mac 下 CMake 的配置与使用

文章目录安装与配置编译单个源文件编译前的准备开始编译编译多个源文件多个源文件在同一目录下多个源文件在不同目录下math 目录下的 CMakeLists.txt根目录的 CMakeLists.txtoption 选项导入外部库本地导入&#xff08;find_package&#xff09;外部导入&#xff08;FetchConte…

五轴编程_沙井万丰数控数控编程五轴编程那个软件好用

沙井万丰数控数控编程五轴编程那个软件好用设计需要掌握很高很全面的知识和技能&#xff0c;模具做的好&#xff0c;产品质量好&#xff0c;模具结构合理&#xff0c;生产效率高&#xff0c;工厂效益好。正因如此&#xff0c;模具技术工在外打工的工资都非常的高。少则每月几千…

Linux学习:第二章-Linux安装

一虚拟机使用 VMware主要特点&#xff1a; 1、不需要分区或重新开机就能在同一台PC上使用两种以上的操作系统 2、本机系统可以与虚拟机系统网络通信 3、可以设定并且随时修改虚拟机操作系统的硬件环境 二安装方式 图形安装&#xff1a;直接回车 字符安装&#xff1a;linux tex…

keil3如何放大字体_国潮海报不会做?送你国风字体+图案笔刷+PSD素材+包装样机...

有很多朋友都问带鱼&#xff0c;国潮风的海报到底应该怎么做呢&#xff1f;首先你要知道什么是国潮风&#xff1a;国潮风就是现代文化和古代文化的碰撞&#xff0c;是年轻人的态度&#xff01;那么应该如何构图如何设计呢&#xff1f;如何配色如何搭配字体呢&#xff1f;这些方…

Google 开源项目风格指南学习笔记——C++篇

文章目录前言0. 缩写名词解释1. 头文件1.1. Self-contained 头文件1.2. 头文件保护1.3. 前置声明1.4 内联函数1.5. #include 的路径及顺序2. 作用域2.1. 命名空间2.2. 非成员函数、静态成员函数和全局函数2.3. 局部变量2.4. 静态和全局变量3. 类3.1. 构造函数的职责3.2. 隐式类…

hiveserver2启动不起来_给爱车配个充电宝,70迈汽车应急启动电源,让你远离搭电小广告...

说到汽车应急启动其实我有切身的痛&#xff0c;在哈尔滨零下35的严冬&#xff0c;晚上带着女神吃完饭&#xff0c;高高兴兴地吃完以后一上车&#xff0c;发现电瓶被冻没电了&#xff0c;天知道当时有多尴尬。马上叫了保险公司过来给搭电&#xff0c;结果在饭店从晚上8点一直等到…

Windows 下 VS 配置 OpenGL 环境

文章目录前言获取 GLFW打开 VS前言 感谢B站同学搬运YouTube上的教学视频。 获取 GLFW 从官网上下载GLFW macOS下64位二进制文件 打开 VS 新建解决方案 OpenGL test&#xff0c;并在解决方案中新建文件夹 Dependencies&#xff1a; 从下载好的 glfw 文件夹中找到最新版链接…

ubuntu 网卡双网口 配置_无线网卡m2 ngff keya keye、minipcie接口改转多口有线网卡实现软路...

小型主板及笔记本中的无线网卡m2ngffkeyakeye接口&#xff08;CNVI除外&#xff09;通过m2ngffkeyae转接pcie1x转接板&#xff0c;或者无线网卡的minipcie接口&#xff0c;通过minipcie转接pcie1x转接板可以改装有线网卡板卡&#xff0c;来实现软路由功能。m2ngffkeyae转接pcie…

OpenGL | 通过绘制一个三角形来入门 OpenGL 图形渲染管线

文章目录前言什么是 OpenGl &#xff1f;回顾openGL 的 Object显存结构工作阶段通过顶点缓冲对象将顶点数据初始化至缓冲中标准化设备坐标顶点缓冲对象 VBOglGenBuffersglBindBufferglBufferData建立了一个顶点和一个片段着色器着色器是什么&#xff1f;为什么需要使用着色器&a…