作业——在线学习Android课程之第七周(HttpURLConnection)

一、HttpURLConnection简介

标准Java接口(java.net) ,HttpURLConnection,可以实现简单的基于URL请求、响应功能。示例如下:

//请求网络数据
private String requestData(String cityName) {
    try {
        URL url = new URL("http://apis.baidu.com/heweather/weather/free?city=" + cityName);
        //某一用于获取天气数据的免费API接口,参数为城市名
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setConnectTimeout(30000);
        //设置连接限时
        connection.setRequestMethod("GET");
        //  设置模式,分GET/POST, 区别如下
        //    a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet, 
        //    b:) post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。

        connection.setRequestProperty("apikey", "56703948b38c34b4a41557b55968739b");
        //设置Header参数APIKEY的值(该API限制)

        connection.connect();
        //以上的设置必须置于该连接命令前

        int responseCode = connection.getResponseCode();
        String responseMessage = connection.getResponseMessage();

        Log.d("MainActivity", "code:" + responseCode);
        String result = null;
        if(responseCode == HttpURLConnection.HTTP_OK){
            InputStream inputStream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine())!= null){
                response.append(line);
            }
        }
        return result;

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

注意事项:
a:) HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。
无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。

b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重, 对connection对象的一切配置(那一堆set函数) 都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。 这些顺序实际上是由http请求的格式决定的。
如果inputStream读操作在outputStream的写操作之前,会抛出例外: java.net.ProtocolException: Cannot write output after reading input…….

c:) http请求实际上由两部分组成, 一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content。
connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,就必须把所有的配置准备好。

d:) 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络, 而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文

二、网络请求为耗时操作,必须异步执行,此处可利用AsyncTask类

class RequestNetworkDataTask extends AsyncTask<String, Integer, String>{

    //在后台处理之前,在主线程中执行(可执行UI操作)
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //UI Loading
    }

    //异步操作,此处执行上述网络请求
    @Override
    protected String doInBackground(String[] params) {
        String str;
        try {
            str = requestData(params[0]);
        } catch (Exception e){
            str = null;
        }
        return str;
    }

    //执行完之后,在主线程中的操作
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        if (s == null){
            Toast.makeText(MainActivity.this, "网络连接失败", Toast.LENGTH_SHORT).show();
            return;
        }
        if (!s.contains("unknown city")) {
            //利用ContentResolver存入数据库,可忽略
            ContentResolver contentResolver = getContentResolver();
            Uri uri = Uri.parse("content://com.example.binh/WeatherData");
            contentResolver.delete(uri, null, null);
            ContentValues values = new ContentValues();
            values.put("city_name", getCityName());
            values.put("city_weather", s);
            contentResolver.insert(uri, values);

            showWeather(s);
            Toast.makeText(MainActivity.this, "天气更新成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, "城市名(拼音)输入有误", Toast.LENGTH_SHORT).show();
        }
    }
}

调用语句:new RequestNetworkDataTask().execute(cityName);

三、网络请求返回的数据多数为JSON格式,可利用GSON解码

第一步,添加GSON支持:

打开Project Structure设置,选择Dependencies标签页,点击“+”,选择“1、Library dependency”,搜索com.google.code.gson:gson:2.6.2(或其他版本),点击OK。

Gson gson = new Gson();
weatherData = gson.fromJson(s, WeatherData.class);

参数s为网络请求返回的jsonString字符串;WeatherData为数据类名,和JSON内的key一一对应。该类可利用GsonFormat插件快速生成:

GsonFormat安装方法:
1、Android studio File->Settings..->Plugins–>Browse repositores..
2、搜索GsonFormat;
3、安装插件;
4、重启android studio。
GsonFormat插件主要是用于一键创建实体类的,创建一个类,在类的内部使用alt+Inset后,在弹出的对话框中将json数据粘贴到里边,json格式正确即可生成对应的类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值