Android第一行代码学习笔记八----网络技术
2016-09-26 11:22
288 查看
1、WebView
借助WebView控件在应用程序里嵌入一个浏览器。首先修改activity_main.xml,示例代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <WebView android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>说明:WebView控件用来显示网页。给它设置了个id,并让它充满整个屏幕。
MainActivity示例代码如下:
public class MainActivity extends Activity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView) findViewById(R.id.web_view); webView.getSettings().setJavaScriptEnabled(true); webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); // 根据传入的参数再去加载新的网页 return true; // 表示当前WebView可以处理打开新网页的请求,不用借助 系统浏览器 } }); webView.loadUrl("http://www.baidu.com"); } }说明:首先获取WebView实例,调用它的getSetting()方法设置一些浏览器属性,实例中只设置支持js脚本。然后调用setWebViewClient()方法,传入WebViewClient匿名类作为参数,重写shouldOveerdeUrlLoading()方法。表明打开网页时使用WebView显示,而不是打开系统浏览器。最后调用WebView的LoadUrl()方法出入url即可。
访问网络需要声明权限,示例如下:
<uses-permission android:name="android.permission.INTERNET" />
2、HTTP访问网络
WebView已经在后台处理好了发送HTTP请求,接收服务响应,解析返回数据,页面展示。现在我们通过手动发送HTTP请求来深入学习。Android 上发送 HTTP 请求的方式一般有两种,HttpURLConnection 和 HttpClient。HttpURLConnection
首先获取到HttpURLConnection实例,示例代码如下:URL url = new URL("http://www.baidu.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection();接着设置HTTP请求方法,包括GET和POST。示例代码如下:
connection.setRequestMethod("GET");然后就定制设置连接超时毫秒数,消息头等。示例如下:
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);再调用 getInputStream()方法就可以获取到服务器返回的输入流,示例如下:
InputStream in = connection.getInputStream();再调用disconnect()方法关闭HTTP连接,示例如下:
connection.disconnect();完整示例如下:
activity_main.xml文件代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/send_request" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send Request" /> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/response" android:layout_width="match_parent" android:layout_height="wrap_content" /> </ScrollView> </LinearLayout>说明:ScrollView控件可以让我们以滚动的形式查看屏幕外的那部分内容。Button发送HTTP请求,TextView显示服务器返回数据。
MainActivity代码示例如下:
public class MainActivity extends Activity implements OnClickListener {说明:开启线程去发送HTTP请求。在主线程中更新UI。
public static final int SHOW_RESPONSE = 0;
private Button sendRequest;
private TextView responseText;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_RESPONSE:
String response = (String) msg.obj;
// 在这里进行UI操作,将结果显示到界面上
responseText.setText(response);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.send_request) {
sendRequestWithHttpURLConnection();
}
}
private void sendRequestWithHttpURLConnection() {
// 开启线程来发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL("http://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
// 下面对获取到的输入流进行读取
BufferedReader reader = new BufferedReader(new
InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
Message message = new Message();
message.what = SHOW_RESPONSE;
// 将服务器返回的结果存放到Message中
message.obj = response.toString();
handler.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
}
网络权限声明示例:
<uses-permission android:name="android.permission.INTERNET" />如果提交方式为POST,则修改代码如下:
connection.setRequestMethod("POST"); DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.writeBytes("username=admin&password=123456");
HttpClient
HttpClient是Apache提供的HTTP网络访问接口,也被引入到Android API中。HttpClient是一个接口,首先需要创建一个DefaultHttpClient实例,代码如下:HttpClient httpClient = new DefaultHttpClient();get请求则创建HttpGet对象()并执行即可
HttpGet httpGet = new HttpGet("http://www.baidu.com"); httpClient.execute(httpGet);post请求则创建HttpPost对象,并传入目标的网络地址
HttpPost httpPost = new HttpPost("http://www.baidu.com");然后创建NameValuePair集合存放参数。并将这个集合传入到UrlEncodedFormEntity,然后调用HttpPost的setEntity()方法将UrlEncodedFormEntity传入
示例代码如下:
<pre name="code" class="java">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); httpClient.execute(httpPost);
执行完后,返回一个HttpResponse对象。首先判定请求是否成功,示例如下
if (httpResponse.getStatusLine().getStatusCode() == 200) { // 请求和响应都成功了 }调用getEntity()获取HttpEntity示例,再调用EntityUtil.toString()这个静态方法将HttpEntity转换成字符串,示例如下:
HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity,"utf-8");MainActivity示例代码:
public class MainActivity extends Activity implements OnClickListener { …… @Override public void onClick(View v) { if (v.getId() == R.id.send_request) { sendRequestWithHttpClient(); } } private void sendRequestWithHttpClient() { new Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet("http://www.baidu.com"); HttpResponse httpResponse = httpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() == 200) { // 请求和响应都成功了 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity, "utf-8"); Message message = new Message(); message.what = SHOW_RESPONSE; // 将服务器返回的结果存放到Message中 message.obj = response.toString(); handler.sendMessage(message); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } …… }到现在,我们已经掌握 HttpURLConnection 和 HttpClient 的基本用法。但是,一个应用程序中可能有多处访问网络,因此我们服用HTTP请求代码。
示例如下:
public class HttpUtil {每次发送请求时代码如下:
public static String sendHttpRequest(String address) {
HttpURLConnection connection = null;
try {
URL url = new URL(address);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);
connection.setDoInput(true);
connection.setDoOutput(true);
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new
InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}
String address = "http://www.baidu.com"; String response = HttpUtil.sendHttpRequest(address);说明:此时我们成功复用了HTTP请求代码。但是也存在问题,网络请求通常属于耗时操作。但是发送请求内部sendHttpRequest()并没有开启线程。这样可能导致主线程调用时被阻塞。而如果在sendHttpRequest()中开启线程,那么服务器响应数据无法返回,sendHttpRequest()方法会在服务器还来得及响应的时候就执行结束。解决办法是使用JAVA回调机制。
首先需要定义一个接口,假设命名为HttpCallbackListener,示例代码如下:
public interface HttpCallbackListener { void onFinish(String response); void onError(Exception e); }说明:接口中有两个方法,onFinish()表示服务器返回成功调用,参数表示服务器返回的 数据。onError表示操作失败调用,参数记录错误的详细信息。
修改HttpUtil代码如下:
public class HttpUtil {说明:sendHttpRequest()方法添加HttpCallbackListener参数,并在方法内部开启子线程。
public static void sendHttpRequest(final String address, final
HttpCallbackListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL(address);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);
connection.setDoInput(true);
connection.setDoOutput(true);
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new
InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
if (listener != null) {
// 回调onFinish()方法
listener.onFinish(response.toString());
}
} catch (Exception e) {
if (listener != null) {
// 回调onError()方法
listener.onError(e);
}
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
}
调用sendHttpRequest()方法需要传入HttpCallbackListener实例,示例代码如下:
HttpUtil.sendHttpRequest(address, new HttpCallbackListener() { @Override public void onFinish(String response) { // 在这里根据返回内容执行具体的逻辑 } @Override public void onError(Exception e) { // 在这里对异常情况进行处理 } });说明:需要注意的是,onFinish()和onError()方法还是在子线程中运行,如果需要UI更新操作,则要使用到异步消息处理机制。
相关文章推荐
- python 网络编程 TCP和UDP
- HTTP状态码大全
- 基于http 和 https的文件下载
- [html] http5
- Http状态码之:301、302重定向
- (4.2.36.1)HTTP之OkHttp(一): Okhttp3使用详解
- Http状态码之:301、302重定向
- 网络编程常见问题总结
- 网络框架-NoHttp
- vmware 下centos7配置网络
- Unity3d面试5 网龙网络
- 基于HTTP协议的多线程下载实现思路
- 如何在ns2中实现一个简单的网络协议
- TCP和UDP的区别
- Servlet获得Http请求,GET/POST
- iOS完美的网络状态判断工具
- http协议
- android使用webview登录,获取session传递到httpclient小例子
- 网络协议分析之路由器之间的链接
- 你掌握了吗?轻松学习grep文本处理工具