这两天由于工作需要,学习了下android通过C#的webservice与服务端进行数据通信(sqlserver)。中间遇到几个问题,总结下,以备后期使用时注意。
Android端调用webservice的代码:
/*** 上传设备状态信息信息*
* @paramdata打包好的数据* @return成功与否的相关字符串
*/publicstaticStringuploadLocation(String data) {METHOD_NAME="UploadLocation";try{SoapObject soapObject = newSoapObject(NAMESPACE,METHOD_NAME);PropertyInfo propertyInfo = newPropertyInfo();propertyInfo.setName("LocationInfo");propertyInfo.setValue(data);
soapObject.addProperty(propertyInfo);
SoapSerializationEnvelopeenvelope = newSoapSerializationEnvelope( SoapEnvelope.VER11);envelope.dotNet=true;envelope.setOutputSoapObject(soapObject);
HttpTransportSE httpTranstation =newHttpTransportSE(URL);httpTranstation.debug=true;httpTranstation.call(NAMESPACE+METHOD_NAME, envelope);Object result = (Object)envelope.getResponse().toString();
if(result !=null) {Log.i("WebserviceControlClass", result.toString());returnresult.toString();}
return"返回数据为空";} catch(Exception e) {e.printStackTrace();
Log.i("WebserviceControlClass","设备信息上传出现异常"+ e.toString());return"出现异常";}
}
需要注意的地方:
1.propertyInfo.setName("LocationInfo");参数要与webservice方法中参数保持一致,否则获取不到数据。
2. envelope.dotNet=true;我用的是dotwebservice的协议,并且用的rpc方式所以,这里要用true.
3. httpTranstation.debug=true;需要用调试模式,所以为true
因为与服务器之间进行通信,是一个耗时的操作,所最后不要再主线程中直接写访问代码。应该通过异步的方式,请求数据。
importandroid.os.AsyncTask;/*** Created by ZHao on 2016/4/15.
*/public classWebServiceTaskextendsAsyncTask{publicWebServiceTask() {}
@Overrideprotected voidonPreExecute() {}
@OverrideprotectedString doInBackground(String... params) {returnWebserviceControlClass.uploadLocation(params[0]);//这里返回webServices请求的值。}@Overrideprotected voidonProgressUpdate(Integer... progress) { }
@Overrideprotected voidonPostExecute(String result) {}
}
然后配合handler实现数据的收发。
/*** 处理设备状态信息 上传和回掉结果*/publicHandlerhandler=newHandler() {@Overridepublic voidhandleMessage(Message msg) {if(msg.what==0) {WebServiceTask task = newWebServiceTask();String result = "";try{task.execute((String) msg.obj);//设置请求参数result = task.get(5000, TimeUnit.MILLISECONDS);//获取返回值,设置超时时间。}catch(InterruptedException e) {e.printStackTrace();
result = "出现异常InterruptedException";} catch(ExecutionException e) {e.printStackTrace();
result = "出现异常ExecutionException";} catch(TimeoutException e) {e.printStackTrace();
result = "出现异常TimeoutException";} catch(Exception e) {result = "出现异常 Exception";}
LogTools.i(TAG, result);}
}
};
因为我需要将一个对象传递到服务端,android调用webservice传输复杂对象,该怎么做呢?
具体的实现方式如下。
首先是android具体操作代码,这里通过handler将locationData传递给异步类,进行数据上传。
dbDeviceStateClass=newDbDeviceStateClass();dbDeviceStateClass.setDevice_id(CommonUtil.getDeviceId(this));//设备idLogTools.i(TAG, CommonUtil.getDeviceId(this));dbDeviceStateClass.setDevice_state_current_lat(String.valueOf(geoLat));//精度dbDeviceStateClass.setDevice_state_current_lon(String.valueOf(geoLng));//纬度dbDeviceStateClass.setDevice_city(location.getCity());//所在城市dbDeviceStateClass.setDevice_province(location.getProvince());//所在省locationData= ConvertForJsonModelControl.ConvertToJsonForDeviceState(dbDeviceStateClass);
Message msg =handler.obtainMessage();
msg.what=0;
msg.obj=locationData;handler.sendMessageDelayed(msg,10);
需要注意的是,传递的对象,android和服务端需要保持一致,在android将数据打包成JSONObject,在服务端在解析出来,服务端代码在下面贴出。
*** 将设备状态信息实体类转换为json对象
* @paramdbDeviceStateClass* @return*/public staticString ConvertToJsonForDeviceState(DbDeviceStateClass dbDeviceStateClass) {String jsonStr = "";JSONObject modelJsonObject = newJSONObject();try{modelJsonObject.put("device_state_id",0);modelJsonObject.put("device_id", dbDeviceStateClass.getDevice_id());modelJsonObject.put("user_name", dbDeviceStateClass.getUser_name());modelJsonObject.put("device_city", dbDeviceStateClass.getDevice_city());modelJsonObject.put("device_province", dbDeviceStateClass.getDevice_province());modelJsonObject.put("device_location", dbDeviceStateClass.getDevice_location());modelJsonObject.put("device_state_current_speed", dbDeviceStateClass.getDevice_state_current_speed());modelJsonObject.put("device_state_update_time", dbDeviceStateClass.getDevice_state_update_time());modelJsonObject.put("device_state_connect_net", dbDeviceStateClass.getDevice_state_connect_net());modelJsonObject.put("device_state_current_lat", dbDeviceStateClass.getDevice_state_current_lat());modelJsonObject.put("device_state_current_lon", dbDeviceStateClass.getDevice_state_current_lon());jsonStr = modelJsonObject.toString();
} catch(JSONException e) {e.printStackTrace();
}
returnjsonStr;
}
接下来是服务端sebservice的具体方法代码,其中这个db_table_device_state 数据类要和android端的DbDeviceStateClass数据类保持一致,才能通过
device_state=(db_table_device_state)jsonSerializer.Deserialize(newJsonTextReader(strReader),typeof(db_table_device_state));将JSONObject数据解析出来。
/// ///保存设备状态到数据库
///
///
///[WebMethod]publicstring UploadLocation(string LocationInfo){
string strJson = "";db_table_device_state device_state = null;try{using (var db = newhudProjecterDBEntities()){
JsonSerializer jsonSerializer = newJsonSerializer();StringReader strReader = newStringReader(LocationInfo);device_state = (db_table_device_state)jsonSerializer.Deserialize(newJsonTextReader(strReader), typeof(db_table_device_state));if(device_state !=null){
var mdevice = db.db_table_device.FirstOrDefault(p => p.device_id == device_state.device_id);
strJson = "mdevice:"+ mdevice;if(mdevice !=null){
db_table_device_state mdevicestate = newdb_table_device_state();mdevicestate.device_state_current_lat = device_state.device_state_current_lat;
mdevicestate.device_state_current_lon = device_state.device_state_current_lon;
mdevicestate.device_state_connect_net = device_state.device_state_connect_net;
mdevicestate.device_state_update_time = DateTime.Now;
mdevicestate.device_state_current_speed = device_state.device_state_current_speed;
db.db_table_device_state.Add(mdevicestate);
db.SaveChanges();
strJson = "[{\"Code\":\"200\",\"Message\":\"操作成功!\"}]";}
}
}
}
catch(Exception ex){
strJson = "[{\"Code\":\"500\",\"Message\":\"服务器出错!\"}]";}
returnstrJson;}
好了,整体流程代码和需要注意的问题都在这里了。吼吼!!