使用HTTP协议访问网络(Android)

  在做项目的过程中需要连接服务器访问数据,还没有接触过Android网络编程方面,参考了《Android第一行代码》,在做的过程中遇到了很多的问题,这里就此记录一下。

 

先给出访问网络的代码

 

首先:在AndroidManifest.xml文件中进行声明,添加如下代码:

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

 

编写网络操作类:

public class HttpUtil{

 public static String sendHttpRequest(String address){

  HttpURLConnection connection=null;
  try{
    URL url=new URL(address);
    connection=(HttpURLConnection)url.openConnection();
    MyLog.d(TAG,"point:2");
    connection.setRequestMethod("GET");
    connection.setConnectTimeout(8000);
    connection.setReadTimeout(8000);
    connection.setDoInput(true);
    connection.setDoOutput(true);
    connection.connect();
    MyLog.d(TAG,"point:3");
    InputStream in=connection.getInputStream();
    MyLog.d(TAG,"point:4");
    BufferedReader reader=new BufferedReader((new InputStreamReader(in)));
    StringBuilder response=new StringBuilder();
    String line;

    while((line=reader.readLine())!=null){
        response.append(line);

    }
    MyLog.d(TAG,"point:5");
    return response.toString();

}catch(Exception e){
    e.printStackTrace();
    return e.getMessage();
}finally{
    if(connection!=null){
        connection.disconnect();
    }
}
}

 

 

发起HTTP请求:

        String address="http://www.baidu.com";

        String reponse=HttpUtil.sendHttpRequest(address);

 

这段代码看似正确,运行的时候会出现错误:java.io.IOException,android.os.NetworkOnMainThreadException

 

先来看第一个错误

   java.io.IOException: Cleartext HTTP traffic to www.baidu.com not permitted

    为保证用户数据和设备的安全,Google针对下一代 Android 系统(Android P) 的应用程序,将要求默认使用加密连接,这意味着 Android P 将禁止 App 使用所有未加密的连接,因此运行 Android P 系统的安卓设备无论是接收或者发送流量,未来都不能明码传输,需要使用下一代(Transport Layer Security)传输层安全协议,而 Android Nougat 和 Oreo 则不受影响。
    因此在Android P 使用HttpUrlConnection进行http请求会出现以下异常。

    W/System.err: java.io.IOException: Cleartext HTTP traffic to www.baidu.com not permitted

 

    使用Okhttp请求则出现:

java.net.UnknownServiceException: CLEARTEXT communication ** not permitted by network security policy

 针对这个问题,参考网上的资料,主要有三种解决方法:

       (1)APP改用https请求

            这个比较简单,这里只需要做如下修改:

          

        String address="https://www.baidu.com";
String response= HttpUtil.sendHttpRequest(address);

 

        (2)targetSdkVersion降到27以下

                  只需要在build.gradle/app里进行修改即可

 

        (3)更改网络安全配置

              这里我就是用的第三种方法,下面来详细说一下步骤。

             1、在res文件夹下创建一个xml文件夹,然后创建一个network_security_config.xml文件,文件中内容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>


             2、在AndroidManifest,xml文件下的application标签添加以下属性:

  <application

      ...

      android:networkSecurityConfig="@xml/network_security_config"

      ...

 />

      当然还有可以不是用引用的方法,会方便一点,直接在主配置文件中添加如下:

         

   android:usesCleartextTraffic="true"

      这两个都可以,这个时候App可以访问网络了。

 

这里主要参考了博客:https://blog.csdn.net/gengkui9897/article/details/82863966

 

 

解决第二个错误

 

主要原因是网络连接不能放在主线程中,这是为了防止进行网络连接主线程被阻塞住。

在Android4.0以后,会发现,只要是写在主线程(就是Activity)中的HTTP请求,运行时都会报错,这是因为Android在4.0以后为了防止应用的ANR(Aplication Not Response)异常,Android这个设计是为了防止网络请求时间过长而导致界面假死的情况发生。

 

有两种解决方案:

1.可以再Activity的onCreate()方法中加入这样一段代码,适用于网络请求数据量很小的话,如下

     if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

     }

 

2、启动子线程进行网络请求,更推荐使用这种

      new Thread(new Runnable(){

            @Override

            public void run(){

                   //进行网络访问操作

            }).start()

 

 

这里主要参考了博客:https://blog.csdn.net/qq_29477223/article/details/81027716

 

 

 

书中后面也给出了更简单的方法,使用OkHttp这里我简单放一下代码:

     1、在build.gradle/app中添加依赖

          implementation ("com.squareup.okhttp3:okhttp:3.14.2")

 

          注:这里OkHttp的版本会有更改,需要到OkHttp在github的官网进行查看,这里我附上网址自行查看:https://github.com/square/okhttp

 

    2、修改HttpUtil中代码

import okhttp3.OkHttpClient;
import okhttp3.Request;

public class HttpUtil {

    private static final String TAG = "HttpUtil";

    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){

        OkHttpClient client=new OkHttpClient();

        Request request=new Request.Builder()
                .url(address)
                .build();
        client.newCall(request).enqueue(callback);

    }
}

 

        

    3、调用代码

String address="http://www.baidu.com";
HttpUtil.sendOkHttpRequest(address,new okhttp3.Callback(){

    @Override
    public void onFailure(Call call, IOException e) {
        //对异常情况进行处理
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        //得到服务器返回的具体内容
        String responseData=response.body().string();
        Log.d(TAG,responseData);
    }
});

 

 

这里使用OkHttp节省了很多代码,并且OkHttp自带的回调接口也节省了我们不少事情。

到这里App就可以正常进行网络访问并得到返回数据了

刚开始学习Android的知识,如果上面有什么错误还请大佬们指出来。

 

参考资料:

《Android第一行代码》第二版,郭霖著

https://blog.csdn.net/gengkui9897/article/details/82863966

https://blog.csdn.net/qq_29477223/article/details/81027716


                
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio中使用HTTP访问网络通常涉及到使用HttpURLConnection或者HttpClient进行网络请求操作。首先,需要在AndroidManifest.xml文件中添加网络权限声明,以允许应用程序进行网络访问。接着,需要在Java代码中创建一个新的线程或者异步任务来执行网络请求操作,因为不能在主线程中执行网络请求,否则会导致程序崩溃。 使用HttpURLConnection进行网络请求时,需要创建一个URL对象,然后通过openConnection()方法得到HttpURLConnection对象。接着,可以设置请求的方法(GET、POST等)、请求头、请求参数等,并发送请求。收到响应后,可以通过getInputStream()方法获取输入流,然后解析和处理服务器返回的数据。 另一种方法是使用HttpClient进行网络请求。需要创建一个DefaultHttpClient对象,并通过HttpGet或HttpPost方法创建请求对象。之后可以设置请求头、请求参数等,并使用execute()方法执行请求。同样,收到响应后可以通过获取输入流来处理返回的数据。 需要注意的是,为了避免在主线程中进行网络请求,可以使用AsyncTask或者Thread来进行异步操作。同时,为了适配Android 9.0及以上版本的系统,还需要在网络请求时进行网络安全性配置,例如使用HTTPS协议或者在清单文件中声明网络安全配置。 总之,在Android Studio中使用HTTP访问网络需要遵循网络请求的基本操作步骤,并且需要适配最新的系统版本和网络安全性规范。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值