編輯:Android開發實例
要做一個優秀的Android應用,使用到網絡通信技術是必不可少的,很難想象一款沒有網絡交互的軟件最終能發展得多成功。那麼我們來看一下,一般Android應用程序裡都是怎麼實現網絡交互的,這裡拿一個Boook對象為例:
如上圖所示,首先在手機端生成一個Book對象,裡面包含書名、作者、價格等數據。為了要將這些數據發送到服務器端,我們要從Book對象中把數據取出,然後組裝成XML格式的字符串。接著通過網絡API,把組裝好的XML字符串發送到服務器端。服務器端接到了客戶端發來的XML字符串,就要對該XML進行解析。然後把解析出的數據重新組裝成Book對象,之後服務器端就可以對該對象進行一系列其它的操作了。
當然XML格式的數據量比較大,現在很多Android應用為了節省流量,都改用JSON格式來傳輸數據了。不過不管是使用XML還是JSON,上圖中描述的步驟總是少不了的。
感覺使用這種方式來傳輸數據,每次封裝和解析XML的過程是最繁瑣的,那麼能不能把這最繁瑣的過程繞過去呢?
如上圖所示,如果可以調用網絡API,直接把Book對象發送到服務器端,那麼整個網絡交互過程就會變得非常簡單,下面我們就來看看如何實現。
新建一個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接口。
接下來打開或新建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="發送"
- />
- </RelativeLayout>
這個布局裡面就是包含了一個按鈕,點擊這個按鈕就去發出網絡請求。
接下來打開或新建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 {
- }
- }
- }
注意由於我們使用了網絡功能,因此需要在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端發送到了服務器端。
好了,今天的講解到此結束,有疑問的朋友請在下面留言。
源碼下載,請點擊這裡
一般來說。熟悉Android程序設計的人都知道Android有三個基礎組件Activity,Service和BroadcastReceiver,他們都是依賴Int
最近一直在調用微信的API,卻發現一直調用不成功,糾結了好久,各方面找教程,找官方,官方裡的文檔也只是寫得很模糊,說是按三步走。 1、申請App_ID
Fragment Android是在Android 3.0 (API level 11)開始引入Fragment的。 可以把Fragment想成Activity中
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放