什麼是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
優勢:編程語言
缺點:分佈式
怎麼使用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>
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); } } }
注意:千萬不要忘記在清單文件中加上權限<uses-permission android:name="android.permission.INTERNET" />
固然,從程序嚴謹的角度來說最好再加上手機是否連網的判斷。
該例子在wifi環境下測試無異常,不保證在使用流量的狀況下也正常。最後的效果以下圖: