2.三种网络接口简述
2.1 标准Java接口
java.net.*提供与联网有关的类,包括流和数据包套接字、Internet协议、常见HTTP处理。
使用java.net.*包连接网络代码:
Java代码 收藏代码
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的请求做了比较好的封装。示例代码如下:
Java代码 收藏代码
//创建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请求,代码如下:
Java代码 收藏代码
//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请求的方式稍有不同,代码如下:
Java代码 收藏代码
//以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请求方式,代码如下:
Java代码 收藏代码
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保存传递参数,代码如下:
Java代码 收藏代码
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程序。
下面是一个服务器和客户端通信的例子。
服务器断代码:
Java代码 收藏代码
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();
}
}
客户端代码:
Java代码 收藏代码
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的网络通信篇基本结束了。