原文地址為:http://blog.csdn.net/guolin_blog/article/details/8967080
要做一個優(yōu)秀的Android應用,使用到網(wǎng)絡通信技術(shù)是必不可少的,很難想象一款沒有網(wǎng)絡交互的軟件最終能發(fā)展得多成功凑队。那么我們來看一下棘钞,一般Android應用程序里都是怎么實現(xiàn)網(wǎng)絡交互的甲脏,這里拿一個Book對象為例:
如上圖所示啰挪,首先在手機端生成一個Book對象兆览,里面包含書名悼沈、作者贱迟、價格等數(shù)據(jù)。為了要將這些數(shù)據(jù)發(fā)送到服務器端絮供,我們要從Book對象中把數(shù)據(jù)取出衣吠,然后組裝成XML格式的字符串。接著通過網(wǎng)絡API壤靶,把組裝好的XML字符串發(fā)送到服務器端缚俏。服務器端接到了客戶端發(fā)來的XML字符串,就要對該XML進行解析贮乳。然后把解析出的數(shù)據(jù)重新組裝成Book對象忧换,之后服務器端就可以對該對象進行一系列其它的操作了。
當然XML格式的數(shù)據(jù)量比較大向拆,現(xiàn)在很多Android應用為了節(jié)省流量亚茬,都改用JSON格式來傳輸數(shù)據(jù)了。不過不管是使用XML還是JSON浓恳,上圖中描述的步驟總是少不了的刹缝。
感覺使用這種方式來傳輸數(shù)據(jù),每次封裝和解析XML的過程是最繁瑣的颈将,那么能不能把這最繁瑣的過程繞過去呢梢夯?
如上圖所示,如果可以調(diào)用網(wǎng)絡API吆鹤,直接把Book對象發(fā)送到服務器端厨疙,那么整個網(wǎng)絡交互過程就會變得非常簡單,下面我們就來看看如何實現(xiàn)疑务。
新建一個Android工程沾凄,命名為ClientTest作為客戶端工程。這里第一個要確定的就是待傳輸?shù)膶ο笾剩覀冃陆ㄒ粋€Book類撒蟀,代碼如下:
package com.test;
import java.io.Serializable;
public class Book implements Serializable {
private String bookName;
private String author;
private double price;
private int pages;
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
}
這個類就是一個簡單的POJO,但是要注意一點温鸽,它實現(xiàn)了Serializable接口保屯,如果想在網(wǎng)絡上傳輸對象手负,那么該對象就一定要實現(xiàn)Serializable接口。
接下來打開或新建activity_main.xml作為程序的主布局文件姑尺,加入如下代碼:
<RelativeLayout 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:background="#000"
tools:context=".MainActivity" >
<Button
android:id="@+id/send"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="發(fā)送"
/>
</RelativeLayout>
這個布局里面就是包含了一個按鈕竟终,點擊這個按鈕就去發(fā)出網(wǎng)絡請求。
接下來打開或新建MainActivity作為程序的主Activity切蟋,其中加入如下代碼:
public class MainActivity extends Activity implements OnClickListener {
private Button send;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
send = (Button) findViewById(R.id.send);
send.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Book book = new Book();
book.setBookName("Android高級編程");
book.setAuthor("Reto Meier");
book.setPages(398);
book.setPrice(59.00);
URL url = null;
ObjectOutputStream oos = null;
try {
url = new URL("http://192.168.1.103:8080/ServerTest/servlet/TestServlet");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.setRequestMethod("POST");
oos = new ObjectOutputStream(connection.getOutputStream());
oos.writeObject(book);
InputStreamReader read = new InputStreamReader(connection.getInputStream());
BufferedReader br = new BufferedReader(read);
String line = "";
while ((line = br.readLine()) != null) {
Log.d("TAG", "line is " + line);
}
br.close();
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
我們可以看到统捶,在onClick方法中處理了按扭的點擊事件。這里首先new出了一個Book對象作為待傳輸數(shù)據(jù)柄粹,接著new出了一個URL對象喘鸟,指明了服務器端的接口地址,然后對HttpURLConnection的一些可選參數(shù)進行配置驻右。接著通過調(diào)用ObjectOutputStream的writeObject方法什黑,將Book對象發(fā)送到服務器端,然后等服務器端返回數(shù)據(jù)堪夭,最后關(guān)閉流和連接愕把。
注意由于我們使用了網(wǎng)絡功能,因此需要在AndroidManifest.xml中加入如下權(quán)限:
<uses-permission android:name="android.permission.INTERNET" />
好了茵瘾,目前Android端的代碼已經(jīng)開發(fā)完成礼华,我們現(xiàn)在開始來編寫服務器端代碼。
新建一個名為ServerTest的Web Project拗秘,要做的第一件事就在Web Project下建立一個和Android端一樣的Book類圣絮。這里有個非常重要的點大家一定要注意,服務器端的Book類和Android端的Book類雕旨,包名和類名都必須相同扮匠,否則會出現(xiàn)類型轉(zhuǎn)換異常。這里由于兩個Book類的內(nèi)容是完全一樣的凡涩,我就不再重復貼出棒搜。
然后新建一個Java Servlet作為網(wǎng)絡訪問接口,我們重寫它的doPost方法活箕,具體代碼如下:
public class TestServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(request.getInputStream());
Book book = (Book) ois.readObject();
System.out.println("書名是: " + book.getBookName());
System.out.println("作者是: " + book.getAuthor());
System.out.println("價格是: " + book.getPrice());
System.out.println("頁數(shù)是: " + book.getPages());
PrintWriter out = response.getWriter();
out.print("success");
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
ois.close();
}
}
}
可以看到力麸,我們首先通過調(diào)用HttpServletRequest的getInputStream方法獲取到輸入流,然后將這個輸入流組裝成ObjectInputStream對象育韩。接下來就很簡單了克蚂,直接調(diào)用ObjectInputStream的readObject方法,將網(wǎng)絡上傳輸過來的Book對象獲取到筋讨,然后打印出Book中攜帶的數(shù)據(jù)埃叭,最后向客戶端返回success。
現(xiàn)在我們來運行一下程序悉罕,首先將ServerTest這個項目布置到服務器上赤屋,并開啟服務器待命立镶。接著在手機上打開ClientTest這個應用程序,如下圖所示:
點擊發(fā)送發(fā)出網(wǎng)絡請求类早,可以看到服務器端打印結(jié)果如下:
而Android端打印結(jié)果如下:
由此我們可以看出媚媒,網(wǎng)絡上進行對象傳輸已經(jīng)成功了!不需要通過繁瑣的XML封裝和解析莺奔,我們也成功將Book中的數(shù)據(jù)完整地從Android端發(fā)送到了服務器端欣范。
好了,今天的講解到此結(jié)束令哟,有疑問的朋友請在下面留言。