第十五章:Android 調用WebService(.net平臺)

什麼是webservice?java

Web service是一個平臺獨立的,低耦合的,自包含的、基於可編程的web的應用程序,可以使用開放的XML標準通用標記語言下的一個子集)標準描述、發佈、發現、協調和配置這些應用程序,用於開發分佈式的互操做的應用程序。Web   Service所使用的是Internet上統1、開放的標準,如HTTP、XML、SOAP(簡單對象訪問協議)、WSDL(webservice描述語言)等,因此Web   Service能夠在任何支持這些標準的環境(Windows,Linux)中使用。(說白了,webService就像是一個方法,只不過不是你本身寫的,並且是跨語言、跨平臺的。咱們只須要調用這個方法得到返回結果便可。至於webservice怎麼運行的與調用端是無關的,也不須要知道)android

注:SOAP協議(Simple   Object   Access   Protocal,簡單對象訪問協議),它是一個用於分散和分佈式環境下網絡信息交換的基於XML的通信協議。在此協議下,軟件組件或應用程序可以經過標準的HTTP協議進行通信。它的設計目標就是簡單性和擴展性,這有助於大量異構程序和平臺之間的互操做性,從而使存在的應用程序可以被普遍的用戶訪問。web

 

爲何要使用webservice?編程

方便而且開放。你們都知道,在手機上的cpu和內存等條件是頗有限的,尤爲是處理一些大數據等易耗損資源的操做都會很是吃力甚至根本就不行。所以,將這一部分的處理交給服務器端,讓服務器來處理這些數據。那麼在服務器端咱們就能夠實現一個webservice讓咱們在客戶端來調用,返回咱們須要的數據便可。 服務器

 

何時使用webservice?網絡

只要是數據交換均可以使用。可是對webservice的優劣要有認識:app

優勢:編程語言

  1. 跨平臺、跨語言;
  2. SOAP協議是基於XML和HTTP這些業界的標準的,獲得了全部的重要公司的支持。
  3. 因爲使用了SOAP,數據是以ASCII文本的方式而非二進制傳輸,調試很方便;而且因爲這樣,它的數據容易經過防火牆,不須要防火牆爲了程序而單獨開一個「漏洞」。
  4. WebService實現的技術難度要比CORBA和DCOM小得多。
  5. 要實現B2B集成,EDI比較完善與比較複雜;而用WebService則能夠低成本的實現,小公司也能夠用上。
  6. 在C/S的程序中,WebService能夠實現網頁無總體刷新的與服務器打交道並取數。

缺點:分佈式

  1. WebService使用了XML對數據封裝,會形成大量的數據要在網絡中傳輸。
  2.  WebService規範沒有規定任何與實現相關的細節,包括對象模型、編程語言,這一點,它不如CORBA 。

 

怎麼使用webservice?(整個過程咱們用一個獲取手機號歸屬地的例子來講明)ide

要使用webservice就必須知道webservice的接口文檔,即WSDL(webservice描述服務)。那麼,WSDL究竟長成什麼樣子呢?

下面我給出了一個連接:(該連接打開就是一個WSDL)

http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl

打開後以下圖所示:(未顯示完整)

家一看就傻眼了吧,怎麼多的信息,到底哪些是咱們須要的呢?

其實,咱們調用webservice只須要三個數據便可:命名空間、方法名稱(包括方法名和參數類型)、根節點。

那麼WSDL上對應的數據在哪裏呢?

根節點便是上面給出的連接去掉「?wsdl」:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx

命名空間、方法名稱(包括方法名和參數類型)在下圖中依次爲從上到下,從左到右。

 

好了,知道了這些。咱們就能夠開始開工了。

首先,咱們須要下載一個ksoap2jar包,它是咱們調用webservice的工具類,在此給出一個下載地址:http://download.csdn.net/detail/af74776/7735251

下載好jar包後導入進項目中(先複製到libs文件夾下,點擊jar包,單擊右鍵,選擇build path ,而後選擇add External Archives。而後,單擊工程項目,單擊右鍵,選擇build path ,再選擇configure build pathxxxxx。在彈出的對話框的右側,選擇Order and Export選項卡。在剛剛添加的ksoap2 jar包前打鉤,而後選擇ok便可)

以下:

成功導入包後,即可開始編寫代碼了(哎,直接上代碼吧。代碼上有詳細的註解):

佈局文件activity_web_service.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingLeft="5dip"
    android:paddingRight="5dip"
    android:paddingTop="5dip" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="手機號碼(段):" />

    <EditText
        android:id="@+id/phone_sec"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="例如:1398547"
        android:inputType="textPhonetic"
        android:singleLine="true" />

    <Button
        android:id="@+id/query_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:text="查詢" />

    <TextView
        android:id="@+id/result_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center_vertical" />

</LinearLayout>
View Code

WebServiceActivity.java:

package com.example.helloandroid;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
//import org.ksoap2.transport.AndroidHttpTransport;
import org.ksoap2.transport.HttpTransportSE;


public class WebServiceActivity extends Activity {
    private EditText phoneSecEditText;
    private TextView resultView;
    private Button queryButton;
    String result;
    private String phoneSec;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_service);
        phoneSecEditText = (EditText) findViewById(R.id.phone_sec);
        resultView = (TextView) findViewById(R.id.result_text);
        queryButton = (Button) findViewById(R.id.query_btn);

        queryButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                phoneSec = phoneSecEditText.getText().toString().trim();
                // 簡單判斷用戶輸入的手機號碼(段)是否合法
                if ("".equals(phoneSec) || phoneSec.length() < 7) {
                    // 給出錯誤提示
                    phoneSecEditText.setError("您輸入的手機號碼(段)有誤!");
                    phoneSecEditText.requestFocus();
                    // 將顯示查詢結果的TextView清空
                    resultView.setText("");
                    return;
                }
                //Android4.0之後便不能夠在主線程中訪問網絡了,所以要新開線程
                Runnable r = new NetWorkHandler();
                Thread thread = new Thread(r);
                thread.start();
                // 因爲網絡鏈接須要必定時間,爲了在主界面上進行網絡信息的展示,暫時用sleep()方法簡單實現,使主線程等待網絡信息讀取完成。
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (result != null) {
                    resultView.setText(result);
                }
            }

        });

    }

    /**
     * 手機號段歸屬查詢
     * 
     * @param phoneSec手機號段
     */
    private void getRemoteInfo(String phoneSec) {
        // 命名空間
        String nameSpace = "http://WebXml.com.cn/";
        // 調用的方法名稱
        String methodName = "getMobileCodeInfo";
        // EndPoint
        String endPoint = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
        // SOAP Action 爲命名空間+方法名稱
        String soapAction = "http://WebXml.com.cn/getMobileCodeInfo";

        // 指定WebService的命名空間和調用的方法名
        SoapObject rpc = new SoapObject(nameSpace, methodName);

        // 設置需調用WebService接口須要傳入的兩個參數mobileCode、userId
        rpc.addProperty("mobileCode", phoneSec);
        rpc.addProperty("userId", "");

        // 生成調用WebService方法的SOAP請求信息,並指定SOAP的版本
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER12);

        envelope.bodyOut = rpc;
        // 設置是否調用的是dotNet開發的WebService
        envelope.dotNet = true;
        // 等價於envelope.bodyOut = rpc;
        envelope.setOutputSoapObject(rpc);

        HttpTransportSE transport = new HttpTransportSE(endPoint);
        try {
            // 調用WebService
            transport.call(soapAction, envelope);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("調用webservice異常");
        }

        // 獲取返回的數據
        SoapObject object = (SoapObject) envelope.bodyIn;
        if (object != null)
            // 獲取返回的結果
            result = object.getProperty(0).toString();
        else {
            System.out.println("object爲空");
        }
    }

    private class NetWorkHandler implements Runnable {

        @Override
        public void run() {
            getRemoteInfo(phoneSec);

        }

    }
}
View Code

注意:千萬不要忘記在清單文件中加上權限<uses-permission android:name="android.permission.INTERNET" />

固然,從程序嚴謹的角度來說最好再加上手機是否連網的判斷。

該例子在wifi環境下測試無異常,不保證在使用流量的狀況下也正常。最後的效果以下圖:

相關文章
相關標籤/搜索