Android开发 - HTTP网络技术

本文详细介绍了Android开发中关于HTTP网络技术的使用,包括WebView的配置与问题解决,HTTP协议的实现,如HttpURLConnection和OkHttp的使用,以及XML和JSON的解析。文中提供了具体的代码示例,涵盖了GET和POST请求,以及如何处理网络权限和混合内容。此外,还探讨了网络编程实践中的回调机制和异步处理。
摘要由CSDN通过智能技术生成


按照顺序本来应该看多媒体的,但是代码实在有点麻烦,算了吧,大不了当成demo就好了。比较有用的好像就是通知栏的通知功能。
看看网络技术,使用HTTP协议和服务器进行交互,并且解析返回的数据。

WebView

可以通过这个控件在应用程序内嵌一个浏览器浏览网址。
布局文件中添加一个WebView

<WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/WebBrowser"></WebView>

修改onCreate()方法,可以通过getSetting()方法设置一些属性,这里只设置了允许js脚本。还有调用了setWebViewClient()方法,参数是一个WebClient实例,表示当需要跳转页面的时候,仍然留在这个WebView,而不是打开系统浏览器。然后加载网址。
这里使用到了网络权限,需要在AndroidManifest.xml中声明权限

<uses-permission android:name="android.permission.INTERNET"/>
protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WebBrowserWebView=findViewById(R.id.WebBrowser);
        WebBrowserWebView.getSettings().setJavaScriptEnabled(true);
        WebBrowserWebView.setWebViewClient(new WebViewClient());
        WebBrowserWebView.loadUrl("http://www.baidu.com");
    }

启动程序,可以看到打开了网页。
image-1

报错

这里有两三个报错。
但是这里如果点击其他链接,浏览器会报错ERR_UNKNOW_URL_SCHEME。
有一个办法是换成WebBrowserWebView.setWebChromeClient(new WebChromeClient());,但是这样就变相调用谷歌浏览器了。
还有个说法是连接不是http://或者https://开头的网址,无法解析协议所以加载不出来。重写这个方法,这里主要用途就是检查网址是否为特定开头,是的话加载页面,否则调用其他浏览器。

WebBrowserWebView.setWebViewClient(new WebViewClient(){
   
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
   
                try{
   
                    if (url.startsWith("http:") || url.startsWith("https:")){
   
                        WebBrowserWebView.loadUrl(url);
                    }else{
   
                        Intent intent=new Intent(Intent.ACTION_VIEW,Uri.parse(url));
                        startActivity(intent);
                    }
                    return true;
                }catch (Exception e){
   
                    return false;
                }
            }
        });

但是点击其他链接后还是会报错
“Uncaught TypeError: Cannot read property ‘getItem’ of null”, source: https://m.baidu.com/?from=844b&vit=fps (2)
添加一个WebView的设置以后,可以访问百度搜索页面了WebBrowserWebView.getSettings().setDomStorageEnabled(true);

这个报错
I/chromium: [INFO:CONSOLE(0)] “Mixed Content: The page at ‘https://m.baidu.com/?from=844b&vit=fps’ was loaded over HTTPS, but requested an insecure image ‘http://shijuezhongguo.cdn.bcebos.com/1/812800023.jpg@s_2,w_370,h_245’. This request has been blocked; the content must be served over HTTPS.”, source: https://m.baidu.com/?from=844b&vit=fps (0)
这主要是因为加载https的时候不能动态加载,先加载http然后加载https。
谷歌在Android5.0以后默认关闭混合模式,https中不能加载http资源了,得手动打开这个功能,还是添加一个设置

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   
            WebBrowserWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }

所以完整代码这样写就可以使用WebView上网冲浪了

protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WebBrowserWebView=findViewById(R.id.WebBrowser);
        WebBrowserWebView.getSettings().setJavaScriptEnabled(true);
        WebBrowserWebView.getSettings().setDomStorageEnabled(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   
            WebBrowserWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        WebBrowserWebView.setWebViewClient(new WebViewClient());
        WebBrowserWebView.loadUrl("http://www.baidu.com");
    }

image-2

HTTP协议访问网络

很简单的原理:客户端向服务器端发一条HTTP请求,服务器收到请求后会返回相应数据给客户端,客户端解析展示出来。
在上一步使用WebView冲浪的时候它已经自己处理好这整个流程了,现在手动看看。

HttpURLConnection

原先的Android有两种发送Http请求的方式,HttpURLConnection和HttpClient。但是后者API太多,扩展困难等问题,很不推荐了,直到Android 6.0终于被废弃了。
获取一个实例。new一个对象,调用openConnection()即可。

URL url = new URL("http://www.baidu.com");
HttpURLConnection connection=(HttpURLConnection)url.openConnection();

得到实例以后就可以使用Http的发给发,GET和POST,如获取数据

connection.setRequestMethos("GET");

还可以对这个连接设置一些其他属性,比如设置连接超时,读取超时的毫秒数、服务器希望得到的一些消息头等等

connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);

然后调用getInputStream()方法获取服务器返回的输入流,对这个流解析即可。

InputStream in=connection.getInputStream();
connection.disconnect();

小栗子
修改一下布局文件,一个Button、一个套着ScrollView的TextView

<?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="com.example.k.androidpractice.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/Test"/>
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/Show"/>
    </ScrollView>

</android.support.constraint.ConstraintLayout>

先编写主方法逻辑,其实看着麻烦,但是有不少都是try-catch。
这里是创建了一个线程运行,new Thread(new Runnable(){…
然后就是正常操作

  • new一个URL对象
  • 调用openConnection()方法建立连接
  • 设置参数,比如GET方法、超时时间等
  • 调用getInputStream()方法接收返回的数据
  • 利用BufferedReader读取InputStream中的数据
  • 展示到TextView中,由于在子线程中不允许修改UI内容,因此这里使用了一个runOnUIThread()方法,这个方法可以让线程切换到主线程去,代码在下面的下面,在这里面进行TextView的文本设置
void sendRequestWithHttpURLConnection(){
   
        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                HttpURLConnection connection=null;
                BufferedReader br=null;
                try {
   
                    URL url = new URL("https://www.baidu.com");
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    InputStream in = connection.getInputStream();
                    br = new BufferedReader(new InputStreamReader(in));
                    //处理返回的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值