Android 网络

WebView用法

参考:《第一行代码》

布局文件:


主体代码:


MainActivity中的代码也很短,首先使用 findViewById()方法获取到了 WebView的实例, 然后调用 WebViewgetSettings()方法可以去设置一些浏览器的属性,这里我们并不去设置过多的属性,只是调用了 setJavaScriptEnabled()方法来让 WebView支持 JavaScript脚本。 接下来是非常重要的一个部分,我们调用了 WebViewsetWebViewClient()方法,并传入了 WebViewClient的匿名类作为参数,然后重写了 shouldOverrideUrlLoading()方法。这就表明当需要从一个网页跳转到另一个网页时,我们希望目标网页仍然在当前 WebView中显示,而不是打开系统浏览器。 最后一步就非常简单了,调用 WebView loadUrl()方法,并将网址传入,即可展示相应网页的内容。

权限设置:


使用 HTTP协议访问网络

Android上发送 HTTP请求的方式一般有两种,HttpURLConnection HttpClient

使用HttpURLConnection

首先需要获取到 HttpURLConnection的实例,一般只需 new出一个 URL对象,并传入目标的网络地址,然后调用一下 openConnection()方法即可,如下所示:

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

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

得到了HttpURLConnection的实例之后,我们可以设置一下 HTTP请求所使用的方法。常用的方法主要有两个,GET POSTGET表示希望从服务器那里获取数据,而 POST则表示希望提交数据给服务器。写法如下:

connection.setRequestMethod("GET");

接下来就可以进行一些自由的定制了,比如设置连接超时、读取超时的毫秒数,以及服务器希望得到的一些消息头等。这部分内容根据自己的实际情况进行编写,示例写法如下:

connection.setConnectTimeout(8000);

connection.setReadTimeout(8000); 

之后再调用 getInputStream()方法就可以获取到服务器返回的输入流了,剩下的任务就是 对输入流进行读取,如下所示:

InputStream in = connection.getInputStream();

最后可以调用 disconnect()方法将这个 HTTP连接关闭掉,如下所示:

connection.disconnect();

 

整体代码:



使用 HttpClient

首先你需要知道,HttpClient是一个接口,因此无法创建它的实例,通常情况下都会创建一个 DefaultHttpClient的实例,如下所示:

HttpClient httpClient = new DefaultHttpClient(); 

接下来如果想要发起一条GET请求,就可以创建一个HttpGet对象,并传入目标的网络地址,然后调用 HttpClientexecute()方法即可:

HttpGet httpGet = new HttpGet("http://www.baidu.com");

httpClient.execute(httpGet); 

如果是发起一条 POST请求会比 GET稍微复杂一点,我们需要创建一个HttpPost对象, 并传入目标的网络地址,如下所示:

HttpPost httpPost = new HttpPost("http://www.baidu.com"); 

然后通过一个NameValuePair集合来存放待提交的参数,并将这个参数集合传入到一个 UrlEncodedFormEntity中,然后调用 HttpPostsetEntity()方法将构建好的 UrlEncodedFormEntity 传入,如下所示:

List<NameValuePair> params = new ArrayList<NameValuePair>();

params.add(new BasicNameValuePair("username", "admin"));

params.add(new BasicNameValuePair("password", "123456"));

UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8"); httpPost.setEntity(entity); 

接下来的操作就和 HttpGet一样了,调用 HttpClientexecute()方法,并将 HttpPost对象传入即可:

httpClient.execute(httpPost); 

执行 execute()方法之后会返回一个 HttpResponse对象,服务器所返回的所有信息就会包含在这里面。通常情况下我们都会先取出服务器返回的状态码,如果等于响应都成功了,如下所示:

if (httpResponse.getStatusLine().getStatusCode() == 200) {

 // 请求和响应都成功了

接下来在这个 if判断的内部取出服务返回的具体内容,可以调用 getEntity()方法获取到一个 HttpEntity实例,然后再用 EntityUtils.toString()这个静态方法将 HttpEntity转换成字符串即可,如下所示:

 HttpEntity entity = httpResponse.getEntity();

 String response = EntityUtils.toString(entity); 

注意如果服务器返回的数据是带有中文的,直接调用EntityUtils.toString()方法进行转换会有乱码的情况出现,这个时候只需要在转换的时候将字符集指定成 utf-8就可以了,如下所示:

String response = EntityUtils.toString(entity, "utf-8");

 

整体代码:



使用OkHttp

Android系统提供了两种HTTP通信类,HttpURLConnectionHttpClient

 关于HttpURLConnectionHttpClient的选择,尽管Google在大部分安卓版本中推荐使用HttpURLConnection,但是这个类相比HttpClient实在是太难用,太弱爆了。OkHttp是一个相对成熟的解决方案,据说Android4.4的源码中可以看到HttpURLConnection已经替换成OkHttp实现了。所以我们更有理由相信OkHttp的强大。

OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一 个IP连接失败的时候,OkHttp会自动尝试下一个IPOkHttp还处理了代理服务器问题和SSL握手失败问题。

使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和java.net.HttpURLConnection一样的API。如果你用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。

http是现在主流应用使用的网络请求方式, 用来交换数据和内容, 有效的使用HTTP可以使你的APP 变的更快和减少流量的使用

OkHttp 是一个很棒HTTP客户端:

· 支持SPDY, 可以合并多个到同一个主机的请求

·  使用连接池技术减少请求的延迟(如果SPDY是可用的话)

·  使用GZIP压缩减少传输的数据量

·  缓存响应避免重复的网络请求

当你的网络出现拥挤的时候,就是OKHttp 大显身手的时候, 它可以避免常见的网络问题,如果你的服务是部署在不同的IP上面的,如果第一个连接失败, OkHTtp会尝试其他的连接. 这个对现在IPv4+IPv6 中常见的把服务冗余部署在不同的数据中心上.  OkHttp 将使用现在TLS特性(SNI ALPN) 来初始化新的连接. 如果握手失败, 将切换到SLLv3

使用OkHttp很容易,同时支持异步阻塞请求和回调.

如果你使用OkHttp ,你不用重写你的代码,   okhttp-urlconnection模块实现了 java.net.HttpURLConnection 中的API,  okhttp-apache模块实现了HttpClient中的API

(一)Http Get

对了网络加载库,那么最常见的肯定就是http get请求了,比如获取一个网页的内容。

//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//创建一个Request
final Request request = new Request.Builder()
        .url("https://github.com/hongyangAndroid")
        .build();
//new call
Call call = mOkHttpClient.newCall(request);
//请求加入调度
call.enqueue(new Callback() {
    @Override
    public void onFailure(Request request, IOException e) {
    }

    @Override
    public void onResponse(final Response response) throws IOException {
        //String htmlStr =  response.body().string();
    }
});

以上就是发送一个get请求的步骤,首先构造一个Request对象,参数最起码有个url,当然你可以通过Request.Builder设置更多的参数比如:headermethod等。

然后通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()cancel()等方法。

最后,我们希望以异步的方式去执行请求,所以我们调用的是call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。

 

ok,需要注意几点:

1. onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()

看到这,你可能会奇怪,竟然还能拿到返回的inputStream,看到这个最起码能意识到一点,这里支持大文件下载,有inputStream我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等,例如:

@Override
public void onResponse ( final Response response)throws IOException
{
    final String res = response.body().string();
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mTv.setText(res);
        }

    });
}

2. 我们这里是异步的方式去执行,当然也支持阻塞的方式,上面我们也说了Call有一个execute()方法,你也可以直接调用call.execute()通过返回一个Response 

() Http Post 携带参数

看来上面的简单的get请求,基本上整个的用法也就掌握了,比如post携带参数,也仅仅是Request的构造的不同。

Request request = buildMultipartFormRequest(
        url, new File[]{file}, new String[]{fileKey}, null);
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("username","张鸿洋");

Request request = new Request.Builder()
        .url(url)
        .post(builder.build())
        .build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
});

大家都清楚,post的时候,参数是包含在请求体中的;所以我们通过FormEncodingBuilder。添加多个String键值对,然后去构造RequestBody,最后完成我们Request的构造。后面的就和上面一样了。

(三)基于Http的文件上传

接下来我们在介绍一个可以构造RequestBodyBuilder,叫做MultipartBuilder。当我们需要做类似于表单上传的时候,就可以使用它来构造我们的requestBody

File file = new File(Environment.getExternalStorageDirectory(), "balabala.mp4");

RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);

RequestBody requestBody = new MultipartBuilder()
        .type(MultipartBuilder.FORM)
        .addPart(Headers.of(
                        "Content-Disposition",
                        "form-data; name=\"username\""),
                RequestBody.create(null, "张鸿洋"))
        .addPart(Headers.of(
                "Content-Disposition",
                "form-data; name=\"mFile\"; 
                filename=\"wjd.mp4\""), fileBody)
        .build();

Request request = new Request.Builder()
        .url("http://192.168.1.103:8080/okHttpServer/fileUpload")
        .post(requestBody)
        .build();

Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
    //...
});

上述代码向服务器传递了一个键值对username:张鸿洋和一个文件。我们通过MultipartBuilderaddPart方法可以添加键值对或者文件。

其实类似于我们拼接模拟浏览器行为的方式,如果对这块不了解,可以参考:从原理角度解析Android Javahttp 文件上传

ok,对于我们最开始的目录还剩下图片下载,文件下载;这两个一个是通过回调的Response拿到byte[]然后decode成图片;文件下载,就是拿到inputStream做写文件操作,我们这里就不赘述了。

关于用法,也可以参考泡网OkHttp使(http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值