يقوم KSoap2 على Android بتجميد الجهاز بدلاً من إجراء مكالمة خدمة ويب

StackOverflow https://stackoverflow.com//questions/25017968

سؤال

أحاول الاتصال به نت 4.0 خدمة ويب قمت بإنشائها لتلقي مكالمات SOAP من أجهزة Android، ويتم استضافتها الآن على IIS المحلية لأغراض تجريبية.

أكتشفت ذلك ksoap2 ستكون مكتبة صفية ممتازة لفعل ما أريد القيام به.تم تنزيل الحزمة .jar من https://code.google.com/p/ksoap2-android/ وبدأت في النقر على لوحة المفاتيح في نشوة...بأصابعي.

تتراوح كمية المعلومات التي يتم إرسالها من بضعة كيلو بايت إلى بضعة ميغا بايت.

ما الذي يعمل

HttpTransportSE.call(String, SoapSerializationEnvelope)- تعمل الطريقة بشكل مثالي بينما لا تزال في محاكي Android الخاص بـ Eclipse، حيث ترسل المكالمة إلى خدمة الويب المستضافة في IIS المحلي.حتى أنه تم اختبار أن خدمة الويب تتلقى مكالمات فارغة من محاولة فتح عنوان الخدمة من متصفح الويب في نفس الشبكة المحلية.

ما لا يعمل

عندما أقوم بنسخ ملف .apk إلى جهاز Android، أقوم بتثبيته، وتشغيله ومحاولة إجراء المكالمة، البرنامج بأكمله يتجمد دون إجراء المكالمة.

كما ترون من كتلة التعليمات البرمجية المقدمة، يتم أخذ بعض الأسطر بعد ذلك في الاعتبار الأخطاء المحتملة:في البيئة التي تمت محاكاتها، تقوم المكالمة الناجحة بإرجاع a الصابون البدائي-كائن أو يتدفق إلى الصحيح كتلة الصيد إنشاء رسالة خطأ للمستخدم وفقًا للوضع الحالي.

ثم على جهاز Android المباشر، يفقد البرنامج استجابته إلى الأبد ويجب إنهاؤه من قائمة التطبيق.

ماذا حاولت

لقد قمت بإزالة المكالمة من الطريقة غير المتزامنة، وحاولت الاتصال بها مباشرة من وظيفة داخلية مجهولة مخصصة لحدث النقر على الزر.

حاولت عدم محاولة الحصول على رد، فقط قمت بإجراء المكالمة.

حاولت الحصول على برنامج logcat للجهاز لمعرفة ما يحدث خلف واجهة المستخدم، ووجدت اثنين، وكانا بحاجة إلى الوصول إلى الجذر، وهو ما لا أمتلكه في الجهاز.لهذا السبب ليس لدي أي logcats لإظهارها لك، ومن المحتمل أن يكون عرض logcat المحاكي عديم الفائدة (؟) لأنه يعمل بشكل جيد هناك.

لا تحاول الاتصال بالمضيف المحلي.

حاولت تثبيت البرنامج على جهاز 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.أنا أيضا لدي أفاست!مكافحة الفيروسات خدمة قيد التشغيل على الكمبيوتر اللوحي الذي أزلت.

هذا حل مشكلتي.يمكن أن يكون ذلك على الأرجح أفاست!برامج مكافحة الفيروسات-برنامج أراد منع كافة الاتصالات من التطبيقات التي لم يتم تنزيلها من اللعب المتجر.أنا لا أعرف إذا كان تغيير الهدف 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();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top