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

Android学习之HttpClient练习(一)

2014-11-03 22:37 330 查看
现在要开始准备毕业设计了。

由于毕业设计里面涉及到Android客户端与服务器,所以,现在先来练习下HttpClient的这种方式。

首先,今天做的基本就是根据:http://www.open-open.com/lib/view/open1329101420890.html(我是根据这篇文章练习的,所以感谢原文作者)

然后整合成了一个完整的Demo,先了解一些HttpClient的一些知识。

具体实现功能是:可以获取某个网页的部分源码,并用字符串显示出来(后续就是可以将其解析为完整的网页等。)

一些改进就是:原文里面的是Android4.0以前的方法,而4.0以后主线程不能执行耗时操作,所以另外开了一个线程来执行网络请求操作,之后通过Handler-Thread的异步方法在其回调方法里面,通知主线程,主线程在做出具体的处理。

11/4日补充:昨天设置客户端上用HttpClient连接网页,于是今天设置在电脑上用J***A写一个普通的Socket服务器。再在Android上写客户端,里面使用Socket协议通过电脑上的外网IP地址即可以连接到电脑的Socket服务器。

注意:PC机可以是通过ADSL连接网络的,因为这样会分给一个外网IP地址。但是如果是通过校园网连接的网络,它给的是一个内网地址,但是如果要连接到内网的服务器,就需要进行端口映射了(由于没有在校园网路由上进行端口映射的权限,所以此路不同)

总结:Android客户端连接PC服务器

1.基于Socket Android客户端直接通过外网IP连接PC服务器

2.基于Http Android客户端通过域名(可以通过域名解析软件来获得一个域名,如花生壳)来访问PC上的服务器。

今天就这么多了,明天继续补充。

主要代码:(几乎和原文里面一样,只是执行线程用的是异步):

/**HttpConnectionUtil辅助类,这里面对POST和GET进行封装*/
public class HttpConnectionUtil {
	/**枚举类型,表示请求类型*/
	public static enum HttpMethod
	{
		GET,POST
	}
	/**异步连接
	 * @param url  网址
	 * @param method  Http方法,POST和GET
	 * @param callback	回调方法,返回给页面或其他的数据
	 * 当形参为final型时,可以保证这个形参的值在方法体运行中不被改变
	 * 注意,由于J***A的基本类型没有引用传值,所以基本类型使用final没有意义
	 * */
	public void asyncConnect(final String url,final HttpMethod method,
			final HttpConnectionCallback callback)
	{
		asyncConnect(url,null,method,callback);
	}
	/**同步方法
	 * @param url 网址
	 * @param method  Http方法,POST和GET
	 * @param callback	回调方法,返回给页面或其他的数据
	 * */
	public void syncConnect(final String url,final HttpMethod method,
			final HttpConnectionCallback callback)
	{
		syncConnect(url,null,method,callback);
	}
	/**异步带参数方法
	 * 另外开启一个线程来执行同步带参函数
	 * 4.0以后不允许主线程里面执行耗时操作
	 * 所以,如果执行完线程操作后,应该是给主消息队列发送消息,通知主界面修改view
	 * */
	public void asyncConnect(final String url,
			final Map<String,String> params,final HttpMethod method,
			final HttpConnectionCallback callback)
	{
		// Handler handler = new Handler();
	        Runnable runnable = new Runnable()
	        {
	            public void run()
	            {
	                syncConnect(url, params, method, callback);
	            }
	        };
	        new Thread(runnable).start();
	       // handler.post(runnable);
	}
	/**同步带参数方法
	 * 里面是耗时操作
	 * */
	public void syncConnect(final String url,
			final Map<String,String> params,final HttpMethod method,
			final HttpConnectionCallback callback)
	{
		 String json = null;
	     BufferedReader reader = null; 
	        try
	        {
	            HttpClient client = new DefaultHttpClient();
	            HttpUriRequest request = getRequest(url, params, method);
	            HttpResponse response = client.execute(request);
	            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
	            {
	                reader = new BufferedReader(new InputStreamReader(response
	                        .getEntity().getContent()));
	                StringBuilder sb = new StringBuilder();
	                for (String s = reader.readLine(); s != null; s = reader
	                        .readLine())
	                {
	                    sb.append(s);
	                }
	 
	                json = sb.toString();
	            }
	        } catch (ClientProtocolException e)
	        {
	            Log.e("HttpConnectionUtil", e.getMessage(), e);
	        } catch (IOException e)
	        {
	            Log.e("HttpConnectionUtil", e.getMessage(), e);
	        } finally//肯定会执行的语句,关闭BufferReader
	        {
	            try
	            {
	                if (reader != null)
	                {
	                    reader.close();
	                }
	            } catch (IOException e)
	            {
	                // ignore me
	            }
	        }
	        callback.execute(json);
	}
	/**
	 * POSY与GET传递参数不同,POST是隐式传递,GET是显示传递
	 * */
	private HttpUriRequest getRequest(String url, Map<String, String> params,
            HttpMethod method)
    {
        if (method.equals(HttpMethod.POST))
        {
            List<NameValuePair> listParams = new ArrayList<NameValuePair>();
            if (params != null)
            {
                for (String name : params.keySet())
                {
                    listParams.add(new BasicNameValuePair(name, params
                            .get(name)));
                }
            }
            try
            {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(
                        listParams);
                HttpPost request = new HttpPost(url);
                request.setEntity(entity);
                return request;
            } catch (UnsupportedEncodingException e)
            {
                // Should not come here, ignore me.
                throw new java.lang.RuntimeException(e.getMessage(), e);
            }
        } else//GET方法是显示传递
        {
            if (url.indexOf("?") < 0)
            {
                url += "?";
            }
            if (params != null)
            {
                for (String name : params.keySet())
                {
                    try
                    {
                        url += "&" + name + "="
                                + URLEncoder.encode(params.get(name), "UTF-8");
 
                    } catch (UnsupportedEncodingException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            HttpGet request = new HttpGet(url);
            return request;
        }
    }
	 /**
     * 回调接口
     *
     */
    public interface HttpConnectionCallback
    {
        /**
         * HTTP请求返回后将会执行回调方法
         * @param response
         *     如果发生任何错误,  http request的 response值将为NUll.
         */
        void execute(String response);
    }
}
Activity里面的代码,如何相应线程传来的消息等

public class CSDemoActivity extends Activity implements OnClickListener{
	private static final String TAG="CSDemoActivity";
	//控件
	private Button btn_httpOk;
	private Button btn_httpCancel;
	private EditText edt_httpAddress;
	private TextView txtview_httpContent;
	//Handler
	private Handler myHandler;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Log.i(TAG,"创建"+TAG);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.cs_demo);
		init();
	}
	/**功能*/
	private void init()
	{
		myHandler=new MyHandler(CSDemoActivity.this);
		bindWidgets();
		setListeners();
	}
	private void bindWidgets()
	{
		btn_httpOk=(Button) findViewById(R.id.btn_httpOk);
		btn_httpCancel=(Button) findViewById(R.id.btn_httpCancel);
		edt_httpAddress=(EditText) findViewById(R.id.edt_httpAddress);
		txtview_httpContent=(TextView) findViewById(R.id.txtView_httpContent);
		edt_httpAddress.setText("http://www.baidu.com");
	}
	private void setListeners()
	{
		btn_httpOk.setOnClickListener(this);
		btn_httpCancel.setOnClickListener(this);
	}
	/**OK功能,请求网络服务*/
	private void onHttpRequest()
	{
		Log.i(TAG,"发送网络请求!");
		txtview_httpContent.setText("正在发送网络请求!");
		  //网址
        String url = edt_httpAddress.getText().toString().trim();
         
        if (!url.equals("http://") && !url.equals(""))
        {
            //自定义类,封装了GET/POST方法,而且同样也封装了同步跟异步的方法
            HttpConnectionUtil conn = new HttpConnectionUtil();
            conn.asyncConnect(url, HttpMethod.GET,
                    new HttpConnectionCallback()
                    {
            			//这个回调函数发送通知给主线程,
                        @Override
                        public void execute(String response)
                        {
                        	 Message msg = myHandler.obtainMessage();
                    		 //Bundle是message中的数据
                    		   Bundle b = new Bundle();
                    		   msg.arg1=1;//arg1表示正常发送数据
                    			 //设置数据
                    		   b.putString("HttpResponse", response);
                    		   msg.setData(b);
                    			 //传消息给主线程
                    		   myHandler.sendMessage(msg);
                        }
                    });
        }

	}
	@Override
	public void onClick(View v) {
		switch(v.getId())
		{
		case R.id.btn_httpOk:
			onHttpRequest();
			break;
		case R.id.btn_httpCancel:
			break;
		}
	}
	/**myHandler类,继承Handler,重写了handleMessage方法*/
	private class MyHandler extends Handler
	{
		private Activity activity;
		public MyHandler(Activity activity)
		{
			 this.activity=new WeakReference<Activity>(activity).get();//使用弱引用避免Handler内存泄露
		}
		//重写handleMessage,用于处理message
		@Override
		public void handleMessage(Message msg) {
			Log.i(TAG,"主线程接收到消息!");
			//选择不同的口令类型
			//0-获取地址失败  1-获取地址成功
			switch(msg.arg1)
			{
			case 0:
				Toast.makeText(activity.getApplicationContext(), "网络请求成功失败!", Toast.LENGTH_SHORT)
				.show();
				Update(msg);
				break;
			case 1:
				Toast.makeText(activity.getApplicationContext(), "网络请求成功!", Toast.LENGTH_SHORT)
				.show();
				Update(msg);
				break;		
			default:
				Toast.makeText(activity.getApplicationContext(), "未知错误!", Toast.LENGTH_SHORT)
				.show();
				Update(msg);
				break;
			}				
		}
		/**更新UI方法*/	
		private void Update(Message msg)
		{
			//这里用于更新网络信息---更新Location
			Bundle b=msg.getData();
			//记得设置bundle时,将Location 键的值设为对应的location
			String response=b.getString("HttpResponse");
			txtview_httpContent.setText(Html.fromHtml(response));
		}
	}
}


我的工程文件:http://download.csdn.net/detail/u010979495/8117027
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: