您的位置:首页 > 理论基础 > 计算机网络

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 {
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();
}
}
说明:开启线程去发送HTTP请求。在主线程中更新UI。

网络权限声明示例:

<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 {
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参数,并在方法内部开启子线程。
调用sendHttpRequest()方法需要传入HttpCallbackListener实例,示例代码如下:
HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {
@Override
public void onFinish(String response) {
// 在这里根据返回内容执行具体的逻辑
}
@Override
public void onError(Exception e) {
// 在这里对异常情况进行处理
}
});
说明:需要注意的是,onFinish()和onError()方法还是在子线程中运行,如果需要UI更新操作,则要使用到异步消息处理机制。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: