`
bigboy
  • 浏览: 167770 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Android之网络与通信

阅读更多

1.题记

本文主要讲述了Android平台中几种网络的通信方式。

2.三种网络接口简述

2.1 标准Java接口

           java.net.*提供与联网有关的类,包括流和数据包套接字、Internet协议、常见HTTP处理。

           使用java.net.*包连接网络代码:

try {
			//定义地址
			URL url=new URL("http://www.google.com");
			//打开连接
			HttpURLConnection http=(HttpURLConnection)url.openConnection();
			//得到连接状态
			int nRC=http.getResponseCode();
			if(nRC==HttpURLConnection.HTTP_OK)
			{
				//取得数据
				InputStream is = http.getInputStream();
				//处理数据
				
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

2.2 Apache接口

          org. apache.http.* 提供的HttpClient对HTTP的请求做了比较好的封装。示例代码如下:

//创建HttpClient
		//这里使用DefaultHttpClient表示默认属性
		HttpClient hc = new DefaultHttpClient();
		//HttpGet实例
		HttpGet get = new HttpGet("http://www.google.com");
		//连接
		try {
			HttpResponse rp = hc.execute(get);
			if(rp.getStatusLine().getStatusCode()==HttpStatus.SC_OK)
			{
				InputStream is = rp.getEntity().getContent();
				//处理数据
			}
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

 

2.3 Android 网络接口

          android.net.*包实际上是通过对Apache中HttpClient的封装来实现的一个HTTP编程接口,同时还提供了HTTP请求队列管理以及HTTP连接池管理,以提高并发请求情况下的处理效率,除此之外还有网络状态监视等接口、网络访问的Socket、常用的Uri类以及有关Wifi相关的类等等。

3. HTTP通信

         在上面的介绍中我们可以看出http的通信方式,有2种方式可以实现HttpURLConnection和HttpClient。

3.1 HttpURLConnection实现HTTP通信

          我们知道在http的请求中主要有2种方式,GET 和 POST。下面我们通过代码看看如何实现的。

          Get方式的HTTP请求,代码如下:

//GET获取数据
public class HttpGetActivity extends Activity
{
	private final String DEBUG_TAG = "Activity02"; 
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.http);		
		TextView mTextView = (TextView)this.findViewById(R.id.TextView_HTTP);
		//http地址
		String httpUrl = "http://192.168.1.110:8080/http1.jsp?name=bigboy";
		//获得的数据
		String resultData = "";
		URL url = null;
		try
		{
			//构造一个URL对象
			url = new URL(httpUrl); 
		}
		catch (MalformedURLException e)
		{
			Log.e(DEBUG_TAG, "MalformedURLException");
		}
		if (url != null)
		{
			try
			{
				//使用HttpURLConnection打开连接
				HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
				//得到读取的内容(流)
				InputStreamReader in = new InputStreamReader(urlConn.getInputStream());
				// 为输出创建BufferedReader
				BufferedReader buffer = new BufferedReader(in);
				String inputLine = null;
				//使用循环来读取获得的数据
				while (((inputLine = buffer.readLine()) != null))
				{
					//我们在每一行后面加上一个"\n"来换行
					resultData += inputLine + "\n";
				}		  
				//关闭InputStreamReader
				in.close();
				//关闭http连接
				urlConn.disconnect();
				//设置显示取得的内容
				if ( resultData != null )
				{
					mTextView.setText(resultData);
				}
				else 
				{
					mTextView.setText("读取的内容为NULL");
				}
			}
			catch (IOException e)
			{
				Log.e(DEBUG_TAG, "IOException");
			}
		}
		else
		{
			Log.e(DEBUG_TAG, "Url NULL");
		}
		//设置按键事件监听
		Button button_Back = (Button) findViewById(R.id.Button_Back);
		/* 监听button的事件信息 */
		button_Back.setOnClickListener(new Button.OnClickListener() 
		{
			public void onClick(View v)
			{
				/* 新建一个Intent对象 */
				Intent intent = new Intent();
				/* 指定intent要启动的类 */
				intent.setClass(Activity02.this, Activity01.class);
				/* 启动一个新的Activity */
				startActivity(intent);
				/* 关闭当前的Activity */
				Activity02.this.finish();
			}
		});
	}
}

         POST请求的方式稍有不同,代码如下:

//以post方式上传参数
public class HttpPOSTActivity extends Activity
{
	private final String DEBUG_TAG = "Activity04"; 
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.http);
		
		TextView mTextView = (TextView)this.findViewById(R.id.TextView_HTTP);
		//http地址"?par=abcdefg"是我们上传的参数
		String httpUrl = "http://192.168.1.110:8080/httpget.jsp";
		//获得的数据
		String resultData = "";
		URL url = null;
		try
		{
			//构造一个URL对象
			url = new URL(httpUrl); 
		}
		catch (MalformedURLException e)
		{
			Log.e(DEBUG_TAG, "MalformedURLException");
		}
		if (url != null)
		{
			try
			{
				// 使用HttpURLConnection打开连接
				HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
				//因为这个是post请求,设立需要设置为true
				urlConn.setDoOutput(true);
				urlConn.setDoInput(true);
		        // 设置以POST方式
				urlConn.setRequestMethod("POST");
		        // Post 请求不能使用缓存
				urlConn.setUseCaches(false);
				urlConn.setInstanceFollowRedirects(true);
		        // 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的
				urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
		        // 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,
		        // 要注意的是connection.getOutputStream会隐含的进行connect。
				urlConn.connect();
				//DataOutputStream流
		        DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
		        //要上传的参数
		        String content = "par=" + URLEncoder.encode("ABCDEFG", "gb2312");
		        //将要上传的内容写入流中
		        out.writeBytes(content); 
		        //刷新、关闭
		        out.flush();
		        out.close(); 
		        //获取数据
		        BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
				String inputLine = null;
				//使用循环来读取获得的数据
				while (((inputLine = reader.readLine()) != null))
				{
					//我们在每一行后面加上一个"\n"来换行
					resultData += inputLine + "\n";
				}		  
				reader.close();
				//关闭http连接
				urlConn.disconnect();
				//设置显示取得的内容
				if ( resultData != null )
				{
					mTextView.setText(resultData);
				}
				else 
				{
					mTextView.setText("读取的内容为NULL");
				}
			}
			catch (IOException e)
			{
				Log.e(DEBUG_TAG, "IOException");
			}
		}
		else
		{
			Log.e(DEBUG_TAG, "Url NULL");
		}
		
		Button button_Back = (Button) findViewById(R.id.Button_Back);
		/* 监听button的事件信息 */
		button_Back.setOnClickListener(new Button.OnClickListener() 
		{
			public void onClick(View v)
			{
				/* 新建一个Intent对象 */
				Intent intent = new Intent();
				/* 指定intent要启动的类 */
				intent.setClass(Activity04.this, Activity01.class);
				/* 启动一个新的Activity */
				startActivity(intent);
				/* 关闭当前的Activity */
				Activity04.this.finish();
			}
		});
	}
}

 默认是使用GET方式。

3.2 HttpClient实现HTTP通信

          HttpClient实现GET请求方式,代码如下:

public class ClientGETActivity extends Activity
{
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.http);
		TextView mTextView = (TextView) this.findViewById(R.id.TextView_HTTP);
		// http地址
		String httpUrl = "http://192.168.1.110:8080/httpget.jsp?par=HttpClient_android_Get";
		//HttpGet连接对象
		HttpGet httpRequest = new HttpGet(httpUrl);
		try
		{
			//取得HttpClient对象
			HttpClient httpclient = new DefaultHttpClient();
			//请求HttpClient,取得HttpResponse
			HttpResponse httpResponse = httpclient.execute(httpRequest);
			//请求成功
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
			{
				//取得返回的字符串
				String strResult = EntityUtils.toString(httpResponse.getEntity());
				mTextView.setText(strResult);
			}
			else
			{
				mTextView.setText("请求错误!");
			}
		}
		catch (ClientProtocolException e)
		{
			mTextView.setText(e.getMessage().toString());
		}
		catch (IOException e)
		{
			mTextView.setText(e.getMessage().toString());
		}
		catch (Exception e)
		{
			mTextView.setText(e.getMessage().toString());
		}  
	
		//设置按键事件监听
		Button button_Back = (Button) findViewById(R.id.Button_Back);
		/* 监听button的事件信息 */
		button_Back.setOnClickListener(new Button.OnClickListener() 
		{
			public void onClick(View v)
			{
				/* 新建一个Intent对象 */
				Intent intent = new Intent();
				/* 指定intent要启动的类 */
				intent.setClass(Activity02.this, Activity01.class);
				/* 启动一个新的Activity */
				startActivity(intent);
				/* 关闭当前的Activity */
				Activity02.this.finish();
			}
		});
	}
}

    HttpClient实现POST请求方式稍有复杂,要求使用NameValuePair保存传递参数,代码如下:

public class ClientPOSTActivity extends Activity
{
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.http);
		TextView mTextView = (TextView) this.findViewById(R.id.TextView_HTTP);
		// http地址
		String httpUrl = "http://192.168.1.110:8080/httpget.jsp";
		//HttpPost连接对象
		HttpPost httpRequest = new HttpPost(httpUrl);
		//使用NameValuePair来保存要传递的Post参数
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		//添加要传递的参数
		params.add(new BasicNameValuePair("par", "HttpClient_android_Post"));
		try
		{
			//设置字符集
			HttpEntity httpentity = new UrlEncodedFormEntity(params, "gb2312");
			//请求httpRequest
			httpRequest.setEntity(httpentity);
			//取得默认的HttpClient
			HttpClient httpclient = new DefaultHttpClient();
			//取得HttpResponse
			HttpResponse httpResponse = httpclient.execute(httpRequest);
			//HttpStatus.SC_OK表示连接成功
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
			{
				//取得返回的字符串
				String strResult = EntityUtils.toString(httpResponse.getEntity());
				mTextView.setText(strResult);
			}
			else
			{
				mTextView.setText("请求错误!");
			}
		}
		catch (ClientProtocolException e)
		{
			mTextView.setText(e.getMessage().toString());
		}
		catch (IOException e)
		{
			mTextView.setText(e.getMessage().toString());
		}
		catch (Exception e)
		{
			mTextView.setText(e.getMessage().toString());
		}  
		//设置按键事件监听
		Button button_Back = (Button) findViewById(R.id.Button_Back);
		/* 监听button的事件信息 */
		button_Back.setOnClickListener(new Button.OnClickListener() 
		{
			public void onClick(View v)
			{
				/* 新建一个Intent对象 */
				Intent intent = new Intent();
				/* 指定intent要启动的类 */
				intent.setClass(Activity03.this, Activity01.class);
				/* 启动一个新的Activity */
				startActivity(intent);
				/* 关闭当前的Activity */
				Activity03.this.finish();
			}
		});
	}
}

4.Socket通信

        在Android中完全可以使用Java标准APilai开发Socket程序。

        下面是一个服务器和客户端通信的例子。

        服务器断代码:

public class Server implements Runnable
{
	public void run()
	{
		try
		{
			//创建ServerSocket
			ServerSocket serverSocket = new ServerSocket(54321);
			while (true)
			{
				//接受客户端请求
				Socket client = serverSocket.accept();
				System.out.println("accept");
				try
				{
					//接收客户端消息
					BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
					String str = in.readLine();
					System.out.println("read:" + str);	
					//向服务器发送消息
					PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(client.getOutputStream())),true);      
					out.println("server message"); 
					//关闭流
					out.close();
					in.close();
				}
				catch (Exception e)
				{
					System.out.println(e.getMessage());
					e.printStackTrace();
				}
				finally
				{
					//关闭
					client.close();
					System.out.println("close");
				}
			}
		}
		catch (Exception e)
		{
			System.out.println(e.getMessage());
		}
	}
	//main函数,开启服务器
	public static void main(String a[])
	{
		Thread desktopServerThread = new Thread(new Server());
		desktopServerThread.start();
	}
}

 

   客户端代码:

public class ClientActivity  extends Activity
{
	private final String		DEBUG_TAG	= "Activity01";
	
	private TextView	mTextView=null;
	private EditText	mEditText=null;
	private Button		mButton=null;
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		mButton = (Button)findViewById(R.id.Button01);
		mTextView=(TextView)findViewById(R.id.TextView01);
		mEditText=(EditText)findViewById(R.id.EditText01);
		
		//登陆
		mButton.setOnClickListener(new OnClickListener()
		{
			public void onClick(View v)
			{
				Socket socket = null;
				String message = mEditText.getText().toString() + "\r\n"; 
				try 
				{	
					//创建Socket
					socket = new Socket("192.168.1.110",54321); 
					//向服务器发送消息
					PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);      
					out.println(message); 
					
					//接收来自服务器的消息
					BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
					String msg = br.readLine(); 
					
					if ( msg != null )
					{
						mTextView.setText(msg);
					}
					else
					{
						mTextView.setText("数据错误!");
					}
					//关闭流
					out.close();
					br.close();
					//关闭Socket
					socket.close(); 
				}
				catch (Exception e) 
				{
					// TODO: handle exception
					Log.e(DEBUG_TAG, e.toString());
				}
			}
		});
	}
}

5.乱码问题

        网络通信中,产生乱码的主要原因是通信过程中使用了不同的编码方式:服务器中的编码方式,传输过程中的编码方式,传输到达终端设备的编码方式。

        解决中文乱码的两个步骤:

 1.使用getBytes("编码方式")来对汉字进行重编码,得到它的字节数组。

 2.再使用new String(Bytes[],"解码方式")来对字节数组进行相应的解码。

 

至此Android的网络通信篇基本结束了。

  • 大小: 85.2 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics