標籤:android style blog http color 使用
現在的行動裝置根本不可能離得開網路連接,資料的交換。最近學習的是在android端如何去調用遠程WebService,都說WebService是一種基於SOAP協議的遠程調用標準,對於這個協議理解不深,知道webservice可以將不同作業系統平台、不同語言、不同技術整合到一塊,android SDK沒有直接調用webservice的庫,最常用的是藉助ksoap2-android這個第三方SDK,點擊開啟連結,然後和其他第三方jar包一樣匯入android項目中即可。
1,定義webservice的NAMESPACE和URL
<string name="nameSpace">http://tempuri.org/</string><string name="serviceURL_203">http://public.ebanji.cn/web5/Server/iSchoolServer.asmx</string>
2,建立HttpTransportSE傳輸對象:HttpTransportSE ht = new HttpTransportSE(SERVICE_URL); SERVICE_URL是webservice提供服務的url
HttpTransportSE ht = new HttpTransportSE(serviceURL);ht.debug=true;
3,執行個體化SoapObject對象:SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName); 第一個參數表示WebService的命名空間,可以從WSDL文檔中找到WebService的命名空間。第二個參數表示要調用的WebService方法名。
SoapObject request = new SoapObject(nameSpace, methodName);
4,使用SOAP1.1協議建立Envelop對象:SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 設定SOAP協議的版本號碼,根據服務端WebService的版本號碼設定。
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
5,設定調用方法的參數值,如果沒有參數,可以省略:例如soapObject.addProperty("name", value);
if(param_list!=null){ for(int i=0;i<param_list.length();i++) { request.addProperty(param_list.getJSONObject(i).getString("name"),param_list.getJSONObject(i).getString("value")); }}
6,設定與.NET提供的webservice保持較好的相容性
envelope.dotNet=true;
7,記得設定bodyout屬性 envelope.bodyOut = soapObject;
envelope.bodyOut=request;envelope.setOutputSoapObject(request);
8,調用webservice:ht.call(SERVICE_NAMESPACE+methodName, envelope);
ht.call(nameSpace+methodName, envelope);
9,解析伺服器響應的SOAP訊息
SoapObject result =(SoapObject) envelope.bodyIn;String resultStr = result.getProperty(0).toString();
附上建進整理的原始碼:
/** * 調用伺服器方法 * @param nameSpace 要調用WebServices的命名空間 * @param serviceURL 要調用WebServices的絕對位址 * @param methodName 要調用WebServices哪個方法名 * @param param_list 要輸入的參數數組,沒有寫null * @return 返回伺服器資料 * @throws JSONException 參數出錯 */private String Get_WebService_1_String(String nameSpace,String serviceURL,String methodName,JSONArray param_list) throws JSONException{ try { SoapObject request = new SoapObject(nameSpace, methodName); if(param_list!=null){ for(int i=0;i<param_list.length();i++) { request.addProperty(param_list.getJSONObject(i).getString("name"),param_list.getJSONObject(i).getString("value")); } } Log.d("Informacation", "參數正確"); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.bodyOut=request; envelope.dotNet=true; envelope.setOutputSoapObject(request); HttpTransportSE ht = new HttpTransportSE(serviceURL); ht.debug=true; Log.d("Informacation","網路是否開啟,訪問地址為:"+serviceURL); ht.call(nameSpace+methodName, envelope); SoapObject result =(SoapObject) envelope.bodyIn; return result.getProperty(0).toString(); } catch (XmlPullParserException e) { // TODO 自動產生的 catch 塊 Log.d("Informacation","XmlPullParserException錯誤:"+e.toString()); }catch(IOException e) { Log.d("Informacation","IO錯誤:"+e.toString()); } catch(Exception e) { Log.d("Informacation","有可能是方法裡面參數不對,或者沒有這個方法,錯誤原因:"+e.toString()); } return "";}
上面這個便是主要實現遠程調用webservice的代碼,其他實現在activity中完成即可,但是這裡也會涉及到一個問題,就是Android多線程問題,在調用webservice時,為了防止ANR的出現,不能在主線程中進行,需要另開子線程執行,,因為子線程涉及到UI更新,Android主線程是線程不安全的
另外開一個線程來調用webservice
/** * 調用的服務為WebService_1 * @param context 要傳入Activity * @param message 用於返回的訊息 * @param methodName 傳入的方法名稱 * @param param_list 要傳入方法的參數和值,如 [{‘name‘:‘方法名‘,‘value‘:‘方法值‘},{‘name‘:‘2‘,‘value‘:‘2‘}] */public void Get_WebService_1_Connect(Message message,String methodName,JSONArray param_list){ this.Target_Message=message; this.NameSpace=context_this.getString(R.string.nameSpace); this.MethodName=methodName; this.Param_List=param_list; if(!isNetworkConnected()){ Toast.makeText(context_this,"網路沒有開啟,請開啟網路", Toast.LENGTH_LONG).show(); return ; } Thread thread=new Thread(runable); thread.start();}
如下為匿名線程類
/** * 線程,把伺服器返回的資料發送出去 */Runnable runable=new Runnable(){ @Override public void run() { try { String value= Get_WebService_1_String(SoapConnect.this.NameSpace,SoapConnect.this.ServiceURL,SoapConnect.this.MethodName
,SoapConnect.this.Param_List); Bundle bundle=Target_Message.getData(); bundle.putString("Data", value); Target_Message.setData(bundle); Target_Message.sendToTarget(); } catch (Exception e) { Log.d("Informacation", "線程出錯"); } }};
接下來只要編寫上面編寫的調用webservice的方法和編寫handle重寫handleMessage方法可以實現調用完成後對資料的處理
編寫的調用webservice的方法
/** * 遠程調用 * * @param Local_MethodName 要返回的本地方法 * @param Remote_MethodName 要調用遠端方法 * @param Param_List 要調用遠程方法的參數 */private void Remote_Calls(MethodName Local_MethodName,int Remote_MethodName, JSONArray Param_List) { // 調用伺服器方法 SoapConnect sc = new SoapConnect(DocumentBoxCenterListActivity.this); myHandler handler = new myHandler(); Message message = handler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putString("MethodName", Local_MethodName.toString()); message.setData(bundle); sc.Get_WebService_1_Connect( message, DocumentBoxCenterListActivity.this.getString(Remote_MethodName), Param_List);}
編寫handle重寫handleMessage方法可以實現調用完成後對資料的處理
/** * 自訂Handler 專門對這個Activity處理伺服器傳送回來的資料 */class myHandler extends Handler { @Override public void handleMessage(Message msg) { Log.e("Informacation", "資料正確返回"); if (msg.getData().get("MethodName") == MethodName.GetDocumentBoxs_Remote.toString()) { GetDocumentBoxs_Remote(msg.getData().getString("Data")); } super.handleMessage(msg); }};