好久没碰见问题解决问题了。前段事件搞网络的东西。一团糟糕。没心情搞了。停了一段时间。反倒是好一些了。网络编程时很大的一块内容。但基本是socket和http这两大块。最开始不太懂。后来一点点的啃。原来安卓中提供的各种类其实就是一层层的继承。一点点将功能加强。将操作简化。怎么说?

httpurlconnection是建立在http之上的连接服务器的方法。是安卓提供的内置类。直接使用。方便快捷。我们知道请求多是post和get两种。而post往往是居多的。跟他的安全性和传输的数据量应该是有分不开的关系。

request。请求

response。响应。

这两个是对立的。有请求就要有响应。这两个好比两个大盒子。客户端要向服务器端发送请求。那就得用到这个盒子。request。有什么话咱里边说。有什么请求都可以往这里边放。当然这是有方法的。具体怎么放。将在下一篇博文中整理介绍一番。

同样的。服务器拿到这个盒子就拆开来看。看看你都发了些什么过来。服务器根据你发的这些东西。用已经写好的一些逻辑例如servlet之类的来处理。处理好的结果装在另外一个箱子response中。又给送回去。

如此这番就完成了和服务器的交互。来看个例子。简单的提交用户名和密码。

首先在myeclipse中新建一个web project命名为FirstServlet再在里边新建一个servlet用来处理从客户端发送过来的用户名和密码。

来看代码

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class firstservlet extends HttpServlet {

	/**
	 * Constructor of the object.
	 */
	public firstservlet() {
		super();
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}

	/**
	 * The doGet method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
                获取输出流来将要返回的信息放进去
                PrintWriter out = response.getWriter();
                获取request中的用户名和密码。实际上就是上面所说的箱子里面的内容
                String usename=request.getParameter("usename");
		String password=request.getParameter("password");
		if("usename".equals(usename)&&"password".equals(password)){
			out.println("httpurlconnection");
		}
		else
			out.println("sorry!");
		out.flush();
		out.close();
	}

	/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
               
		doGet(request,response);
	}

	/**
	 * Initialization of the servlet. <br>
	 *
	 * @throws ServletException if an error occurs
	 */
	public void init() throws ServletException {
		// Put your code here
	}

}

这个代买很简单。就是判断用户名和密码是否是指定好的。并没有去连接数据库那么复杂的操作。

接下来要在客户端也就是安卓代码了。

布局文件时两个edittext用来输入用户名密码。一个button用来提交。一个textview来显示服务器处理返回的结果。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/usename"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/tijiao"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="提交" />

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</LinearLayout>



然后是activity的代码。

package com.example.httpurlconnection;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

	URL url = null;
	String result ="";
	String susename = null;
	String spassword = null;
	TextView textview;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		final EditText usename = (EditText) findViewById(R.id.usename);
		final EditText password = (EditText) findViewById(R.id.password);
		final Handler handler=new Handler(){
			@Override
			public void handleMessage(Message msg) {
				if(msg.what==0x1233)
					textview.setText(result);
			}
		};
		textview = (TextView) findViewById(R.id.textview);
		Button tijiao = (Button) findViewById(R.id.tijiao);
		tijiao.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				result ="";
				susename = usename.getText().toString();
				spassword = password.getText().toString();
				StringBuffer stringBuffer = new StringBuffer();
				//post请求中传递参数的格式是 参数名=参数&参数名1=参数1的形式
                                stringBuffer.append("usename=").append(susename).append("&password=").append(spassword);
				final byte[] data = stringBuffer.toString().getBytes();
				new Thread() {
					@Override
					public void run() {
						try {
                                                        //这个地址就是你的web所在的地址。用控制台的ipconfig去查ip。
                                                         url = new URL(
									"http://192.168.1.101:8080/FirstServlet/servlet/firstservlet");
						} catch (MalformedURLException e) {

							e.printStackTrace();
						}
						try {
							Log.d("===========================", "进入了函数体");
                                                        //打开连接                                                     
                                                        HttpURLConnection ction = (HttpURLConnection) url
									.openConnection();
							ction.setRequestMethod("POST");//设置连接方式。默认是get
							ction.connect();
							Log.d("===========================", "连接成功");
							OutputStream os = ction.getOutputStream();//获取输出流来往请求体request中写入数据
							os.write(data);
							InputStream is = ction.getInputStream();//获取输入流。也就是响应response的返回数据
							Log.d("===========================", "输入流获取成功");
							BufferedReader in = new BufferedReader(
									new InputStreamReader(is));
							
							String line = null;
							while ((line = in.readLine()) != null) {
								result += line;
							}
							Log.d("===========================", "result获取成功");
							Log.d("===========================",result );
							handler.sendEmptyMessage(0x1233);
							Log.d("===========================", "显示成功");
							is.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}.start();
			}

		});
		
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

获取了相应的控件之后。为button增加一个点击事件函数。

在函数中可以看到。是创建了一个线程。这个是需要注意的。网络连接的部分最好是用一个新线程来做。因为 如果你的网络不好的情况下。不会一直等待。很影响客户体验。在4.0后的版本如果不新启动一个线程来处理网络编译是无法通过的。

还需要注意的一点是。(这里博主其实也不太清楚原理)如果直接是在setonclick之外新建线程来处理网络。可以直接在线程中用textview。settext来设置文本显示返回数据。但是在setonclick之中新建线程是不行的。报错说要原始线程来改变ui。所以这里新建了一个handler。用来在新建的线程和ui线程也就是主线程来通讯。获得了result之后就通知主线程更新数据。

看下结果。

如何获取android downloads目录_java

输入的用户名和指定的一样。返回httourlconnection

如何获取android downloads目录_android_02

提交的数据和指定的不一样返回sorry。和服务器的处理代码完全吻合了。