Android 上の KSoap2 が Web サービス呼び出しを行う代わりにデバイスをフリーズする

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

質問

に接続しようとしています .NET 4.0 Android デバイスから SOAP 呼び出しを受信するために作成した Web サービスは、現在ホストされています ローカル IIS テスト目的のため。

そうだと分かった ksoap2 私がやりたいことを実現するための優れたクラスライブラリになるでしょう。.jar パッケージを次からダウンロードしました https://code.google.com/p/ksoap2-android/ そして恍惚のあまりキーボードを叩き始めました...私の指で。

送信される情報の量は、数キロバイトから数メガバイトです。

何が機能しているのか

HttpTransportSE.call(String, SoapSerializationEnvelope)-method は、Eclipse の Android エミュレータ内でも完全に機能し、ローカル IIS でホストされている Web サービスに呼び出しを送信します。同じローカル エリア ネットワーク内の Web ブラウザからサービス アドレスを開こうとすると、Web サービスが空の呼び出しを受信することもテストされました。

何がうまくいかないのか

.apk ファイルを Android デバイスにコピーし、インストールして起動し、電話をかけようとすると、プログラム全体が フリーズする 電話をかけずに。

コード ブロックの数行後には、考えられるエラーが考慮されていることがわかります。エミュレートされた環境では、呼び出しが成功すると、 ソーププリミティブ-オブジェクトまたは正しいものに流れ込む キャッチブロック 現在の状況に応じてユーザーにエラー メッセージを生成します。

その後、ライブ Android デバイスでは、プログラムの応答性が永久に失われ、アプリケーション メニューから終了する必要があります。

私は何を試しましたか

非同期メソッドから呼び出しを削除し、ボタンのクリック イベントに割り当てられた匿名の内部関数から直接呼び出してみました。

応答を得ようとせず、ただ電話をかけてみました。

UI の背後で何が起こっているかを確認するためにデバイスの logcat プログラムを取得しようとしましたが、2 つ見つかりました。それらには root アクセスが必要でしたが、デバイスにはそれがありませんでした。これが、表示できる logcat がない理由です。エミュレーターの 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 と同じレベルに下げました。私も持っていました アバスト!ウイルス対策 削除したタブレット上で実行されているサービス。

これで私の問題は解決しました。それはおそらく Avast! かもしれません。ウイルス対策プログラムは、Play ストアからダウンロードされていないアプリケーションからのすべての通信をブロックしたいと考えていました。ターゲット SDK を変更したことが実際に大きな効果をもたらしたかどうかはわかりません。

他のヒント

次のようなことをしている可能性はありますか?

YourAsyncTask task = new YourAsyncTask();
WebServiceResult result = task.doInBackground();

それは間違っている、完全に間違っているからです。電話したら doInBackground() 直接同じで実行されます Thread そして新しいものではありません。を開始する必要があります。 AsyncTaskexecute() このような:

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