巧用Android網絡通訊技術,在網絡上直接傳輸對象

本文首發於CSDN博客,轉載請註明出處:http://blog.csdn.net/guolin_blog/article/details/8967080java

要作一個優秀的Android應用,使用到網絡通訊技術是必不可少的,很難想象一款沒有網絡交互的軟件最終能發展得多成功。那麼咱們來看一下,通常Android應用程序裏都是怎麼實現網絡交互的,這裏拿一個Boook對象爲例:android

如上圖所示,首先在手機端生成一個Book對象,裏面包含書名、做者、價格等數據。爲了要將這些數據發送到服務器端,咱們要從Book對象中把數據取出,而後組裝成XML格式的字符串。接着經過網絡API,把組裝好的XML字符串發送到服務器端。服務器端接到了客戶端發來的XML字符串,就要對該XML進行解析。而後把解析出的數據從新組裝成Book對象,以後服務器端就能夠對該對象進行一系列其它的操做了。編程

固然XML格式的數據量比較大,如今不少Android應用爲了節省流量,都改用JSON格式來傳輸數據了。不過無論是使用XML仍是JSON,上圖中描述的步驟老是少不了的。服務器

感受使用這種方式來傳輸數據,每次封裝和解析XML的過程是最繁瑣的,那麼能不能把這最繁瑣的過程繞過去呢?網絡

如上圖所示,若是能夠調用網絡API,直接把Book對象發送到服務器端,那麼整個網絡交互過程就會變得很是簡單,下面咱們就來看看如何實現。ide

新建一個Android工程,命名爲ClientTest做爲客戶端工程。這裏第一個要肯定的就是待傳輸的對象,咱們新建一個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,可是要注意一點,它實現了Serializable接口,若是想在網絡上傳輸對象,那麼該對象就必定要實現Serializable接口。this

接下來打開或新建activity_main.xml做爲程序的主佈局文件,加入以下代碼:url

<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="發送"
     />

</RelativeLayout>

這個佈局裏面就是包含了一個按鈕,點擊這個按鈕就去發出網絡請求。spa

接下來打開或新建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對象做爲待傳輸數據,接着new出了一個URL對象,指明瞭服務器端的接口地址,而後對HttpURLConnection的一些可選參數進行配置。接着經過調用ObjectOutputStream的writeObject方法,將Book對象發送到服務器端,而後等服務器端返回數據,最後關閉流和鏈接。

注意因爲咱們使用了網絡功能,所以須要在AndroidManifest.xml中加入以下權限:

<uses-permission android:name="android.permission.INTERNET" />

好了,目前Android端的代碼已經開發完成,咱們如今開始來編寫服務器端代碼。

新建一個名爲ServerTest的Web Project,要作的第一件事就在Web Project下創建一個和Android端同樣的Book類。這裏有個很是重要的點你們必定要注意,服務器端的Book類和Android端的Book類,包名和類名都必須相同,不然會出現類型轉換異常。這裏因爲兩個Book類的內容是徹底同樣的,我就再也不重複貼出。

而後新建一個Java Servlet做爲網絡訪問接口,咱們重寫它的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("頁數是: " + book.getPages());
            PrintWriter out = response.getWriter();
            out.print("success");
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ois.close();
        }
    }
    
}

能夠看到,咱們首先經過調用HttpServletRequest的getInputStream方法獲取到輸入流,而後將這個輸入流組裝成ObjectInputStream對象。接下來就很簡單了,直接調用ObjectInputStream的readObject方法,將網絡上傳輸過來的Book對象獲取到,而後打印出Book中攜帶的數據,最後向客戶端返回success。

如今咱們來運行一下程序,首先將ServerTest這個項目佈置到服務器上,並開啓服務器待命。接着在手機上打開ClientTest這個應用程序,以下圖所示:

                            

點擊發送發出網絡請求,能夠看到服務器端打印結果以下:

而Android端打印結果以下:

由此咱們能夠看出,網絡上進行對象傳輸已經成功了!不須要經過繁瑣的XML封裝和解析,咱們也成功將Book中的數據完整地從Android端發送到了服務器端。

好了,今天的講解到此結束,有疑問的朋友請在下面留言。

源碼下載,請點擊這裏

相關文章
相關標籤/搜索