在学习Android的网络连接时遇到崩溃或异常(出现的问题就这两个,但是不稳定)的问题,先上代码,看看哪里错了(答案在文末)

activity_main.xml:

 <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <EditText
android:id="@+id/et_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入网址"
android:text="https://www.baidu.com/" /> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click"
android:text="查看" /> <ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"> <TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView> </LinearLayout> </android.support.constraint.ConstraintLayout>

MainActivity.xml:

 import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL; public class MainActivity extends AppCompatActivity { private EditText et_path;
private TextView tv_result; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); et_path = findViewById(R.id.et_path);
tv_result = findViewById(R.id.tv_result); } //点检就进行查看指定路径的源码
public void click(View view) { try {
//获取源码路径
String path = et_path.getText().toString().trim();
//创建url对象制定我们要访问的路径
URL url = new URL(path);
//拿到httpUrlConnection对象
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//设置请求方法
httpURLConnection.setRequestMethod("GET");//GET要求大写,默认get请求
//设置请求时间
httpURLConnection.setConnectTimeout(5000);
//获取服务器返回的状态码
int code = httpURLConnection.getResponseCode();
//如果code = 200,说明请求成功
if (code == 200) {
//获取服务器返回的数据,是以流的形式返回的
InputStream in = httpURLConnection.getInputStream();
System.out.println(); //将流转换成字符串
String content = StreamTools.readStreamToString(in); //展示到指定控件中
tv_result.setText(content); }
} catch (ProtocolException e) {
e.printStackTrace();
System.out.println("异常1");
} catch (MalformedURLException e) {
e.printStackTrace();
System.out.println("异常2");
} catch (IOException e) {
e.printStackTrace();
System.out.println("异常3");
} }
}

新建一个工具类来将Stream流转换成String

SrreamTools.java:

 import android.content.Context;

 import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream; public class StreamTools {
//把inStream转换成String
public static String readStreamToString(InputStream in) throws IOException {
//定义一个内存输出流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int len = -1;
byte[] buffer = new byte[1024];//1kb
while ((len = in.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, len);
}
in.close();
String content = new String(byteArrayOutputStream.toByteArray());
return content;
}
}

加权限

<?xml version="1.0" encoding="utf-8"?>
<manifest ……> <uses-permission android:name="android.permission.INTERNET"/> <application>
……
</application> </manifest>

以上就是出现错误的全部代码。虽然在有一些情况下会运行成功,但不久你就会发现,会崩的或者是出现异常3(不要学我写System.out.println("异常3"),要用Log,这里边与小白参考)。
上网查询问题,通过课本查询,都没有发现解决方法。网上有很多人问,有人说要在新的线程中写,有人说权限(其实一般不会发生这种低级问题),感觉回答的也是一些小白。很多并没有参考性。其中回答线程的应该是有些功底的了,下面我就发一下解决方法。

因为在4.0之后谷歌强制要求连接网络不能在主线程进行访问,所以以上的代码时不能上网的,即使加了权限也不行。此时我们为您将联网的逻辑写在新的线程中。

获取了网络信息后需要将信息展示在控件上(比如TextView),此时遇到了新的问题:更新UI异常。

这是因为更新UI必须在主线程中进行,所以引入新的API——Handler,重写Handler.handlerMessage()方法来进行更新UI;来要注意一个细节,Toast也是一个View,所以也不能在子线程中运行,也需要放在handlerMessage()中。

又有问题了:如何将在子线程要进行的逻辑在handlerMessage()中进行呢?也就是说主线程和子线程需要一个联系,不然怎么更新UI。所以新建Message对象,用Handler的sendMessage()向主线程发送Message对象,在主线程中接收,这样zhuxiancheng 就可以根据子线程发来的信息来进行应做的逻辑了。

说了这么多,不知同没听懂,还是代码实在

只需要修改MainActivity.java:

 package com.lgqchinese.httphaha;

 import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL; public class MainActivity extends AppCompatActivity { private EditText et_path;
private TextView tv_result;
private static final int REQUESTSUEECSS = 0;
private static final int REQUESTNOTFOUNT = 1; //在主线程中定义Handler
private Handler handler = new Handler() {
//重写方法 @Override
public void handleMessage(Message msg) { //区分发来的消息时哪一条
switch (msg.what){
case REQUESTSUEECSS://代表请求成功
String content = (String) msg.obj;
tv_result.setText(content);
break;
case REQUESTNOTFOUNT://请求失败
Toast.makeText(getApplicationContext(), "请求资源不存在", Toast.LENGTH_SHORT).show();
break; } }
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); et_path = findViewById(R.id.et_path);
tv_result = findViewById(R.id.tv_result); //打印当前线程的名字
System.out.println("当前线程的名字" + Thread.currentThread().getName()); } //点检就进行查看指定路径的源码
public void click(View view) { //创建一个子线程
new Thread() {
@Override
public void run() {
try {
//获取源码路径
String path = et_path.getText().toString().trim();
//创建url对象制定我们要访问的路径
URL url = new URL(path);
//拿到httpUrlConnection对象
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//设置请求方法
httpURLConnection.setRequestMethod("GET");//GET要求大写,默认get请求
//设置请求时间
httpURLConnection.setConnectTimeout(5000);
//获取服务器返回的状态码
int code = httpURLConnection.getResponseCode();
//如果code = 200,说明请求成功
if (code == 200) {
//获取服务器返回的数据,是以流的形式返回的
InputStream in = httpURLConnection.getInputStream();
System.out.println(); //将流转换成字符串
String content = StreamTools.readStreamToString(in); //创建Message对象
Message msg = new Message();
msg.what = REQUESTSUEECSS;
msg.obj = content;
//用创建的Handler(助手)告诉系统要更新UI
handler.sendMessage(msg); //展示到指定控件中
// tv_result.setText(content); } else {
//请求资源不存在,Toast是一个view,也不能再子线程更新UI
Message msg = new Message();
msg.what = REQUESTNOTFOUNT;
handler.sendMessage(msg);
// Toast.makeText(getApplicationContext(), "请求资源不存在", Toast.LENGTH_SHORT).show();
} } catch (ProtocolException e) {
e.printStackTrace();
System.out.println("异常1");
} catch (MalformedURLException e) {
e.printStackTrace();
System.out.println("异常2");
} catch (IOException e) {
e.printStackTrace();
System.out.println("异常3");
}
}
}.start(); }
}

可以在异常处再向主线程发信息,来提示用户加载失败,这里不再赘述,自练即可。

以上就是今天遇到的问题,个人感觉就是

因为在4.0之后谷歌强制要求连接网络不能在主线程进行访问

 

学习Android过程中遇到的问题及解决方法——网络请求的更多相关文章

  1. 学习Android过程中遇到的问题及解决方法——电话监听

    也许有时你会有这样一个需求:通电话时有一个重要的事需要记下来或者和一个陌生人特别是大骗子通话时,这是就想如果能把通话录下来就方便多了.(这才是我写这个代码的目的!!!) 在此过程中,犯了一个很大的错误 ...

  2. 学习Android过程中遇到的问题及解决方法——AS为xutils添加依赖

    在使用xutils时遇到不能添加以来的问题,花了很长时间终于解决,网上添加依赖的方法很多,在此针对个人出现的问题作下笔记. 我本想使用jar包,因为在使用smartImageView时是用的jar包来 ...

  3. 国内不fq安装K8S四: 安装过程中遇到的问题和解决方法

    目录 4 安装过程中遇到的问题和解决方法 4.1 常见问题 4.2 常用的操作命令 4.3 比较好的博客 国内不fq安装K8S一: 安装docker 国内不fq安装K8S二: 安装kubernet 国 ...

  4. 将html代码部署到阿里云服务器,并进行域名解析,以及在部署过程中遇到的问题和解决方法

    本博客主要是说一下,,如何将html代码部署到阿里云服务器,并进行域名解析,以及在部署过程中遇到的问题和解决方法. 1.先在阿里云上购买一台阿里云服务器(ECS云服务器): 2.远程连接上该服务器,在 ...

  5. 学习Android过程中的一些博客或工具收集

    android studio中使用SlidingMenu: 超简单Android Studio导入第三方库(SlidingMenu)教程绝对傻瓜版 android 更新sdk23以后,报错提示Floa ...

  6. 学习Android过程中遇到的未解决问题(个人笔记,细节补充,随时更新)

    201811/13 使用HttpURLConnection对象调用方法又出现IO异常,我又百度个博客搜寻答案,未果.下午试试真机,完美.自己建了服务器tomcat,编写android访问自己tomca ...

  7. 蘑菇街TeamTalk编译连接过程中遇到的问题及解决方法(iOS)

    今天浏览博文的时候,“蘑菇街开源的即时通讯框架,包括iOS.Android.Mac.Windows客户端和后台 Github源码下载地址:https://github.com/mogujie/Team ...

  8. 2016最新cocoapods安装流程,安装过程中遇到的问题及解决方法

    现在的cocoapods与之前比较.有很多不一样的地方.自己试了一试,终于搞定.现在大概纪录一下. 1.首先查看ruby是否是最新版的. ruby是通过rvm安装的所以需要先安装rvm后查看ruby是 ...

  9. caffe安装过程中遇到的问题以及解决方法

    1. 在安装依赖库的时候,遇到: @gxjun-Latitude-E5440:~$ sudo apt-get install libatlas-base-dev 正在读取软件包列表... 完成 正在分 ...

随机推荐

  1. Leetcode 26. Remove Duplicates from Sorted Array (easy)

    Given a sorted array, remove the duplicates in-place such that each element appear only once and ret ...

  2. 网络编程-TCP/IP

    TCP/IP五层模型讲解(2分) 我们将应用层,表示层,会话层并作应用层,从tcp/ip五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议 就理解了整个互联网通信的原理. 首先,用户感知到的 ...

  3. STL queue用法

    先进先出 #include<iostream> #include<algorithm> #include<cstdio> #include<stack> ...

  4. centos7下安装python3.6

    一.wget 官网下载到本地 进入家目录: cd ~ wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz下载到本地 解压移动到/ ...

  5. 线程中的current thread not owner异常错误

    多线程常用的一些方法: wait(),wait(long),notify(),notifyAll()等 这些方法是当前类的实例方法, wait()      是使持有对象锁的线程释放锁;wait(lo ...

  6. 常用ASCII码对照表

        

  7. 【学习总结】Git学习-参考廖雪峰老师教程二-安装Git

    学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...

  8. 解决linux用户切换失败 su:execute /usr/bin 没有权限

    问题描述: 回宿舍前,在root用户中安装fish,并修改其shell为fish.回宿舍之后,在图形界面用root用户进行登陆,莫名其妙登陆失败.没有任何提示信息,直接回到登陆界面.用非root用户登 ...

  9. Linux下设置MySql自动启动

    https://www.cnblogs.com/sunny3096/p/7954146.html

  10. 安全测试学习之bWAPP环境搭建

    安装环境:window7+IIS+mysql+php bWAPP下载地址:https://sourceforge.net/projects/bwapp/files/bee-box/  ,直接点击Dow ...