用户的响应性:

Android中,应用的响应性被活动管理器(ActivityManager)和窗口管理器(WindowManager)这两个系统服务所监视。当用户触发了输入事件(如键盘输入,点击按钮等),如果应用6秒内没有响应用户的输入事件,那么,Android会认为该应用无响应,便弹出ANRApplicationNoResponse)对话框。如下图。

在正常情况下,Android程序会在一条单线程里运行。如果Activity要处理一件比较耗时的工作,应该交给子线程完成,否侧会因为主线程被阻塞,后面的用户输入事件因没能在5秒内响应,导致应用出现ANR对话框。

HTTP协议

大多数的Android应用程序都会使用HTTP协议来发送和接收网络数据,而Android中主要提供了两种方式来进行HTTP操作,HttpURLConnectionHttpClient。这两种方式都支持HTTPS协议、以流的形式进行上传和下载、配置超时时间、IPv6、以及连接池等功能。

HttpURLConnection

HttpURLConnection是一种多用途、轻量极的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。虽然HttpURLConnectionAPI提供的比较简单,但是同时这也使得我们可以更加容易地去使用和扩展它。

不过在Android2.2版本之前,HttpURLConnection一直存在着一些令人厌烦的bug。比如说对一个可读的InputStream调用close()方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是直接禁用掉连接池的功能:


通过web的完全模拟,android为我们提供了HttpURLConnection对象,我们可以向网络发送请求参数.

我们在请求jsp页面时,如图所示网页发送的网络请求


请求头分析

Accept:客户机通过这个头,告诉服务器,它支持哪些数据类型

Accept-Charset::客户机通过这个头,告诉服务器,它支持的编码

Accept-Encoding:客户机通过这个头,告诉服务器,支持哪种数据压缩格式

Accept-Language:客户机采用的是哪个语言

Host:客户机通过这个头,告诉服务器,想访问服务器哪台主机

If-Modified-Since:客户机通过这个头,告诉服务器,数据缓存的时间

Referer:客户机通过这个头,告诉服务器,客户机是从哪个页面来的(防盗链)

User-Agent:说明客户机操作系统信息,以及浏览器信息

Cookie:客户机通过这个头,可以带点数据给服务器

Connection

响应头分析

Location:服务器通过这个头告诉浏览器去访问哪个页面,这个头通常配合302状态码使用

Content-Encoding:服务器通过这个头告诉浏览器,回送的数据采用的压缩格式

Content-Length:服务器通过这个头告诉浏览器,回送的数据的大小

Content-Type:服务器通过这个头告诉浏览器,回送数据的类型

Last-Modified:服务器通过这个头告诉浏览器,资源的最后修改时间

Refresh:服务器通过这个头告诉浏览器,定时刷新网页

Content-Disposition:attachment;filename=aaa.zip:服务器通过这个头告诉浏览器,以下载方式打开数据

ETag:W/"7777-1242234904000":缓存相关的头,为每一个资源配一个唯一的编号

Expires:0

Cache-Control:no-cache

Pragma:no-cache这三个头组合使用,让浏览器不要缓存数据

最常用的Http请求无非是getpostget请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servletpostget的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。

案例

运行效果:

<!-- 添加网络访问权限 -->

<uses-permission android:name="android.permission.INTERNET"/>


布局文件 activity_login.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content" >    <TextView        android:id="@+id/username"        android:layout_width="wrap_content"android:layout_height="wrap_content" android:textSize="20sp"android:layout_alignBaseline="@+id/editusername"android:text="@string/username"/>        <EditText        android:id="@+id/editusername"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_toRightOf="@+id/username"        android:hint="@string/edit_username"        />            <TextView        android:id="@+id/password"        android:layout_width="wrap_content"android:layout_height="wrap_content" android:textSize="20sp"android:layout_below="@+id/username"android:layout_alignBaseline="@+id/editpass"android:text="@string/password"/>        <EditText        android:id="@+id/editpass"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_toRightOf="@+id/password"        android:layout_below="@+id/editusername"        android:hint="@string/edit_password"        />    <Button        android:id="@+id/btn_login"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="80dp"        android:layout_below="@+id/password"         android:layout_marginLeft="50dp"        android:text="@string/btn_sure"        android:onClick="login"        />        <CheckBox         android:id="@+id/checkbox"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="50dp"        android:layout_alignBaseline="@+id/btn_login"        android:layout_below="@+id/editpass"        android:layout_toRightOf="@+id/btn_login"       android:text="@string/checkbox"       />        <TextView        android:id="@+id/tv_result"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:text="@string/tip_result"/></RelativeLayout> 


String.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <string name="app_name">lesson03</string>    <string name="hello_world">Hello world!</string>    <string name="action_settings">Settings</string>    <string name="username">用户名</string><string name="password">密码</string>   <string name="edit_username">请输入用户名</string><string name="edit_password">请输入密码</string> <string name="btn_sure">确定</string>    <string name="checkbox">是否记住密码</string>        <string name="tip_result">服务器返回的数据</string></resources>


流转字符工具类 StreamTools.java

package com.example.util;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;public class StreamTools {/** * 把流轉換成字符串 * @param is * @return */public static String streamToStr(InputStream is){try {// 字节的输出流ByteArrayOutputStream os = new ByteArrayOutputStream();// 定义读取长度int len = 0;// 定义缓冲区byte buffer[] = new byte[1024];// 从输入流中读取,并写入os对象中while ((len = is.read(buffer)) != -1) {os.write(buffer, 0, len);}// 关闭流is.close();os.close();// 写到字节流return new String(os.toByteArray());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}}}


Activity类LoginActivity.java

package com.example.android_http;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.URL;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.text.TextUtils;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import com.example.util.StreamTools;public class LoginActivity extends Activity {private EditText et_username;private EditText et_password;private TextView tv_result;private final int CHANGETEXTVIEW = 1;//消息处理者private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);int what = msg.what;//标识switch (what) {case CHANGETEXTVIEW://这个消息就改变TextView控件的操作String result = (String) msg.obj;//附带的对象tv_result.setText(result);//改变控件内容Toast.makeText(LoginActivity.this, result, Toast.LENGTH_LONG).show();break;default:break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);findView();}/** * 查找控件 */public void findView() {et_password = (EditText) findViewById(R.id.editpass);et_username = (EditText) findViewById(R.id.editusername);tv_result = (TextView) findViewById(R.id.tv_result);}/** * 登陆按钮操作 * @param v */public void login(View v) {// 获取点击控件的idint id = v.getId();// 根据id进行判断switch (id) {case R.id.btn_login:// 进行登录操作// 获取用户名密码final String userName = et_username.getText().toString();final String userPass = et_password.getText().toString();// 判断是否为空if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(userPass)) {Toast.makeText(getApplicationContext(), "用户名或者密码不能为空", 0).show();} else {Toast.makeText(getApplicationContext(), "发送请求道服务器", 0).show();// 访问网络 (需要一个网络的权限) <uses-permission android:name="android.permission.INTERNET"/>// 访问网络(耗时的操作) 避免阻塞主线程(UI) 需要开启新的子线程来处理new Thread() {public void run() {//调用get或者post请求postOper(userName, userPass);};}.start();}break;default:break;}} public void postOper(String userName,String userPass){try {// 请求地址String spec = "http://172.16.237.144:8080/Login/LoginServlet";// 根据地址创建URL对象(网络访问url)URL url = new URL(spec);// 采用http协议打开的连接对象HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();urlConnection.setRequestMethod("POST");// 以get方式发起请求urlConnection.setReadTimeout(5000);// 设置超时urlConnection.setConnectTimeout(5000);// 设置连接超时//传递的数据String data = "username"+userName+"&userpass"+userPass;//设置请求头urlConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");//设置请求头urlConnection.setRequestProperty("Connection","keep-alive");//设置请求头urlConnection.setRequestProperty("Content-Length",String.valueOf(data.getBytes().length));//设置请求头urlConnection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");//post 流的方式写入urlConnection.setDoInput(true);//发送post请求必须设置允许输入urlConnection.setDoOutput(true);//发送post请求必须设置允许输出OutputStream os = urlConnection.getOutputStream();os.write(data.getBytes());os.flush();// 获取相应的 code 400 200 505 302if (urlConnection.getResponseCode() == 200) {// 得到网络返回的输入流InputStream is = urlConnection.getInputStream();//通过工具类处理String result = StreamTools.streamToStr(is);Message msg = new Message();msg.what = CHANGETEXTVIEW;//消息的唯一标志msg.obj = result;//改变的内容通过object传过去handler.sendMessage(msg);//发送消息System.out.println("返回的数据是:" + result);} else {System.out.println("请求url失败");}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}/** * 通过get方式发送请求 * @param userName * @param userPass */public void getOper(String userName,String userPass){try {// 请求地址String spec = "http://172.16.237.144:8080/Login/LoginServlet?username="+ userName + "&userpass=" + userPass;// 根据地址创建URL对象(网络访问url)URL url = new URL(spec);// 采用http协议打开的连接对象HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();urlConnection.setRequestMethod("GET");// 以get方式发起请求urlConnection.setReadTimeout(5000);// 设置超时urlConnection.setConnectTimeout(5000);// 设置连接超时urlConnection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0");// 获取相应的 code 400 200 505 302if (urlConnection.getResponseCode() == 200) {// 得到网络返回的输入流InputStream is = urlConnection.getInputStream();//通过工具类处理String result = StreamTools.streamToStr(is);Message msg = new Message();msg.what = CHANGETEXTVIEW;//消息的唯一标志msg.obj = result;//改变的内容通过object传过去handler.sendMessage(msg);//发送消息System.out.println("返回的数据是:" + result);} else {System.out.println("请求url失败");}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}



更多相关文章

  1. PHP将数据库查询内容转换为JSON格式且显示中文
  2. 国外的通过Binder类创建Bound Service例子Create a Bound Servic
  3. Android的SQLite使用实例
  4. Android中自定义数据适配器Adapter
  5. android笔记-android基本操作和数据存储
  6. Android利用Fiddler进行网络数据抓包【怎么跟踪微信请求】
  7. Android之JSON全面解析与使用
  8. android xml-----Sax解析
  9. Android几个面试题解答

随机推荐

  1. Android(安卓)Launcher研究(一)---------
  2. Android上访问Java做的WebService获取JSO
  3. 优秀的Android计算器
  4. 一行代码使Android状态栏变沉浸式透明化
  5. 利用 LeakCanary 来检查 Android(安卓)内
  6. 融云 Android(安卓)sdk 2.1+ 稳定版 UI
  7. android修改TextView中部分文字的颜色来
  8. Android使用矢量图(SVG, VectorDrawable)实
  9. Android中的dp
  10. java后台程序员转android 《二》之 集成