Android——网络操作基础

在Android app中,网络操作是不可或缺的一个模块,手机中数据的上传下载都需要通过app中的网络操作模块进行。

在Android进行http请求操作有多种方式,在这里我简单说一下最基础的用HttpURLConnection进行网络操作的方法

一、向设备申请网络权限

首先需要向设备申请网络权限。

如果是Android9.0以前版本的设备,只需要在AndroidManifest.xml文件中添加一个与<application>同级的标签即可

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

 从Android9.0开始增加了对http请求的限制,在添加上面的标签之后,还需要我们另外创建安全配置文件

1、在res文件夹下创建xml/network-security-config.xml文件

2、在netnetwork-security-config.xml中添加cleartextTrafficPermitted属性(是否允许网络通信使用明文网络流量)

xml文件内容如下:

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

3、指定安全配置文件

在AndroidManifest中的Application标签里申明配置文件

android:networkSecurityConfig="@xml/network_security_config"

二、在Activity中进行http请求

首先在mainlayout中创建一个id为myclick的Button。

然后是在Activity中的操作:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainlayout);
    }
        public void get() {
            try {
                //实例化URL对象
                URL url = new URL("http://www.imooc.com/api/teacher?type=3&cid=1");

                //获取HTTPURLConnection实例
                HttpURLConnection httpconn = (HttpURLConnection)url.openConnection();

                //设置请求相关属性
                //设置方式
                httpconn.setRequestMethod("GET");
                //设置请求时长
                httpconn.setConnectTimeout(5000);
                //获取响应码     200:成功   404:未请求到指定资源  500:服务器异常
                if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    InputStream in = httpconn.getInputStream();
                    byte[] b = new byte[1024];
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    int length = 0;
                    while ((length = in.read(b)) > -1) {
                        //不能不做判断直接in.read(b),因为若数据读完了,输入流还会继续读,只是内容为空,这时循环会继续。
                        // 而当in.read()取值为-1时则代表已经没有内容了
                        baos.write(b, 0,length);
                    }
                    String str = new String(baos.toString());
                    Log.i("MainActivity", str + "----------------");
                };
            }
            catch (MalformedURLException e1) {
                e1.printStackTrace();
            } catch (IOException e2) {
                e2.printStackTrace();
            }
        }

    public void myclick(View view) {
        switch(view.getId()) {
            case R.id.get:
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        get();
                    }
                }.start();
            break;
        }
    }
}

在做好前面两步后安装apk到设备中,点击按钮即可在AS中的Logcat中查看获取到的信息。

三、可能遇到的报错

在这里简单列举在网络操作中可能遇到的一些报错情况:

1、NetworkOnMainThreadException

如果遇到NetworkOnMainThreadException报错的,则说明网络请求操作在主线程中进行了,我们需要开一个子线程进行网络请求

如前面我给出的例子,则是将get()操作放在子线程中进行:

public void myclick(View view) {
        switch(view.getId()) {
            case R.id.get:
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        get();
                    }
                }.start();
            break;
        }
    }

 

2、SecurityException

遇到java.lang.SecurityException: Permission denied (missing INTERNET permission?)

这种报错的一般是没有在AndroidManifest中申请网络权限

解决办法:在AndroidManifest文件中<application>标签外添加网络权限申请标签:

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

 

3、NetworkSecurityConfig

遇到这种报错是因为在Android9.0后面的版本增加了对http请求的限制,需要我们另外创建安全配置文件:

1)在res文件夹下创建xml/network_security_config.xml文件

2)在network_security_config.xml文件中添加cleartextTrafficPermitted属性

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

3)指定安全配置文件

在AndroidManifest.xml中的Application添加申明(引用刚才创建的安全配置文件的地址)

android:networkSecurityConfig="@xml/network_security_config"

 

4、SocketException

这种情况一般为多次调试程序后出现,如新添加的配置文件没有安装进设备,则可能出现这个exception

解决方法:卸载程序后重新安装运行即可


拓展:

Android P的新特性:网络安全配置

Android 9中全面禁止了非安全的http连接,如果要使用非加密连接,则需要配置network security config文件。

1、首先,在res/xml文件夹下建立network security config文件,名字任意,可以命名为network-security-config.xml

2、在netnetwork-security-config.xml中添加cleartextTrafficPermitted属性(是否允许网络通信使用明文网络流量)

xml文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!-- 允许所有网址使用非安全连接-->
    <base-config cleartextTrafficPermitted="true"/>
</network-security-config>

应用可以使用 base-config(应用范围的自定义)或 domain-config(针对每个网域的自定义)自定义自己的连接。

例如,应用可能需要确保所有与 secure.example.com 的连接始终通过 HTTPS 完成,以防止来自恶意网络的敏感流量。

这时可以这样配置: 

<?xml version="1.0" encoding="utf-8"?>

<network-security-config>
    <!-- 不允许secure.example.com网域使用非安全连接 -->
    <domain-config cleartextTrafficPermitted="false">

        <domain includeSubdomains="true">secure.example.com</domain>

    </domain-config>

</network-security-config>

3、指定安全配置文件

在AndroidManifest中的Application标签里声明配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network-security-config"
                    ... >
        ...
    </application>
</manifest>

除此之外,我们还可以配置信任的CA证书。

配置自定义 CA

假设您要连接到使用自签名 SSL 证书的主机,或者连接到其 SSL 证书由您信任的非公共 CA(如公司的内部 CA)颁发的主机。

res/xml/network-security-config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <!-- 自己的非公共CA -->
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

以 PEM 或 DER 格式将自签名或非公共 CA 证书添加到 res/raw/my_ca

限制可信 CA 集

如果应用并不一定想要信任系统信任的所有 CA,则可以自行指定,即缩减要信任的 CA 集。这样可防止应用信任由任何其他 CA 颁发的欺诈性证书。

限制可信 CA 集的配置与针对特定网域信任自定义CA 相似,不同的是,前者要在资源中提供多个 CA。

res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">secure.example.com</domain>
        <domain includeSubdomains="true">cdn.example.com</domain>
        <trust-anchors>
            <certificates src="@raw/trusted_roots"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

以 PEM 或 DER 格式将可信 CA 添加到 res/raw/trusted_roots。请注意,如果使用 PEM 格式,文件必须仅包含 PEM 数据,且没有额外的文本。您还可以提供多个 <certificates>,而不是只提供一个。 

信任其他 CA

应用可能需要信任系统不信任的其他 CA,出现此情况的原因可能是系统还未包含此 CA,或 CA 不符合添加到 Android 系统中的要求。应用可以通过为一个配置指定多个证书源来实现此目的。

res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="@raw/extracas"/>
            <certificates src="system" /> <!-- 系统内置的CA证书 -->
            <certificates src="user" /> <!-- 用户自己安装的CA证书 -->
        </trust-anchors>
    </base-config>
</network-security-config>

拓展部分借鉴资料链接:

Android P新特性、 网络安全配置|Android Developers

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值