KSoap2 на Android замораживает устройство вместо вызова веб-сервиса
-
21-12-2019 - |
Вопрос
Я пытаюсь подключиться к .NET 4.0 веб-сервис, который я создал для приема SOAP-вызовов с Android-устройств, теперь размещен на локальный IIS в целях тестирования.
я узнал что ksoap2 была бы отличной библиотекой классов для того, что я хочу делать.Скачал пакет .jar с сайта https://code.google.com/p/ksoap2-android/ и начал в экстазе стучать по клавиатуре...пальцами.
Объем отправляемой информации составляет от нескольких килобайт до нескольких мегабайт.
Что работает
HttpTransportSE.call(String, SoapSerializationEnvelope)
-метод отлично работает, пока находится в эмуляторе Android Eclipse, отправляя вызов веб-сервису, размещенному в локальном IIS.Даже проверил, что веб-сервис получает пустые вызовы при попытке открыть адрес службы из веб-браузера в той же локальной сети.
Что не работает
Когда я копирую .apk-файл на Android-устройство, устанавливаю его, запускаю и пытаюсь позвонить, вся программа замерзает не сделав звонка.
Как видно из блока кода, представленного несколькими строками, после этого учитываются возможные ошибки:В эмулируемой среде успешный вызов возвращает МылоПримитивное-объект или впадает в правильное поймать блок генерирование сообщения об ошибке для пользователя в соответствии с текущей ситуацией.
Затем на работающем устройстве Android программа навсегда теряет работоспособность, и ее необходимо закрыть из меню приложения.
Что я пробовал
Я удалил вызов из асинхронного метода и попробовал вызвать его прямо из анонимной внутренней функции, назначенной для события нажатия кнопки.
Старался не ждать ответа, а просто позвонить.
Попробовал получить программу logcat для устройства, чтобы посмотреть, что происходит за пользовательским интерфейсом, нашел две, им нужен root-доступ, которого у меня нет в устройстве.Вот почему у меня нет логарифмов, которые я мог бы вам показать, а показывать логарифм эмулятора, вероятно (?), будет бесполезно, потому что там он работает нормально.
Не пытаюсь подключиться к локальному хосту.
Пробовал установить программу на старый планшет Lenovo под управлением Андроид 4.2.2 и на новом Samsung Galaxy Tab оба будут иметь одну и ту же проблему, хотя в остальном работают хорошо.
Код
Вот асинхронный метод вызова в устройстве/эмуляторе, где переменные str_URL
и soapRequest
являются правильным адресом службы (проверено) и правильно сформированным SoapObject соответственно:
@Override
protected WebServiceResult doInBackground(Void... v) {
WebServiceResult _ret;
SoapSerializationEnvelope soapEnvelope= new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet=true;
soapEnvelope.setAddAdornments(false);
soapEnvelope.setOutputSoapObject(soapRequest);
HttpTransportSE conn = new HttpTransportSE(str_URL);
conn.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
conn.debug = true;
try {
conn.call(str_ACTION, soapEnvelope);
SoapObject o = (SoapObject)soapEnvelope.getResponse();
_ret = new WebServiceResult(o, WebServiceResultEnum.ok);
} catch (NetworkOnMainThreadException e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.keskeytys);
} catch (HttpResponseException e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.httpVirhe);
} catch (XmlPullParserException e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.vaara_muoto);
} catch (SocketTimeoutException e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.aikakatkaisu);
} catch (Exception e) {
_ret = new WebServiceResult(null, WebServiceResultEnum.keskeytys);
}
return _ret;
}
Заранее спасибо!
Решение 2
Кажется, я заявил минимальный SDK как 14 и целевой SDK как 17 в AndroidManifest.xml.Я не использовал никаких необычных вещей в новых SDK, поэтому понизил целевой SDK до того же уровня, что и минимальный SDK, 14.у меня тоже был Аваст!Антивирус служба работает на планшете, который я удалил.
Это решило мою проблему.Возможно, это Avast!антивирусная программа хотела заблокировать все сообщения приложений, не загруженных из Play-store.Я не знаю, имело ли изменение целевого SDK большой эффект.
Другие советы
Возможно ли, что вы делаете что-то вроде этого:
YourAsyncTask task = new YourAsyncTask();
WebServiceResult result = task.doInBackground();
Потому что это было бы неправильно, совершенно неправильно.Если вы позвоните doInBackground()
непосредственно он будет работать в том же Thread
и не в новом.Вам необходимо начать AsyncTask
с execute()
так:
YourAsyncTask task = new YourAsyncTask();
task.execute();
Вам необходимо реализовать AsyncTask
так:
public class ExampleTask extends AsyncTask<Void, Void, WebServiceResult> {
public interface FinishedListener {
public void onFinished(WebServiceResult result);
}
private final FinishedListener finishedListener;
public ExampleTask(FinishedListener listener) {
this.finishedListener = listener;
}
@Override
protected WebServiceResult doInBackground(Void... params) {
WebServiceResult result = ...;
return result;
}
@Override
protected void onPostExecute(WebServiceResult result) {
super.onPostExecute(result);
if(this.finishedListener != null) {
this.finishedListener.onFinished(result);
}
}
}
И если вы реализовали это таким образом, вы можете использовать его так:
ExampleTask task = new ExampleTask(new ExampleTask.FinishedListener() {
@Override
public void onFinished(WebServiceResult result) {
// This will be called if the task has finished
}
});
task.execute();