1

Androidでボタンをクリックすると、簡単なプロジェクトを実行しています。Java でコーディングされた Web サービスから返されたメッセージが表示されます。

Android用のEclipseでの私のプログラムは次のとおりです。

@Override
public void onClick(View v) {
    final String url = "http://10.0.2.2:8050/WebPractice/PracticeWebServices?wsdl";
    final String namespace = "http://PracticeWebServices/";
    final String methodName = "hello";
    final String action = namespace + methodName;

    if(v.getId() == submit_btn.getId()) {
        SoapObject so = new SoapObject(namespace, methodName);
        so.addProperty("name", "Arjun");
        SoapSerializationEnvelope sse = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        sse.setOutputSoapObject(so);
        HttpTransportSE hse = new HttpTransportSE(url);

        try {
            hse.call(action, sse);
            SoapPrimitive primitive = (SoapPrimitive)sse.getResponse();
            Toast.makeText(getApplicationContext(),primitive.toString() , Toast.LENGTH_SHORT);
        } catch(IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
    }
}

以下はJavaでの私のコードです:

@WebService(serviceName = "PracticeWebServices")
public class PracticeWebServices {

    @WebMethod(operationName = "hello")
    public String hello(@WebParam(name = "name") String name) {
        return "Hello " + name + " !";
    }
}

マニフェスト ファイルにインターネット アクセス許可を含めました。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

今、Eclipseで提供されているエミュレーターでファイルを実行しているとき。ボタンをクリックすると、メッセージが表示されますUnfortunately the program has stopped

logCat を確認すると.... android.os.NetworkOnMainThreadExceptionで例外が発生したようです

4

5 に答える 5

2

インターネットリソース、ディスク上のデータなど、メインスレッドで長時間のキーパープロセスを呼び出さないでください。代わりに、バックグラウンドタスクを使用する必要があります。そうしないと、前述のようにANRエラーまたはコンパイルエラーが発生します。

于 2013-01-15T17:55:44.613 に答える
2

長いネットワークフェッチ操作をまたはのいずれかに配置する必要がありThreadますAsyncTask

使用することをお勧めしますAsyncTask

classあなたはそれを作成することによってこのようなことをすることができますextends AsyncTask

private class LongNetworkOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {

        SoapObject so = new SoapObject(namespace, methodName);
        so.addProperty("name", "Arjun");
        SoapSerializationEnvelope sse = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        sse.setOutputSoapObject(so);
        HttpTransportSE hse = new HttpTransportSE(url);

        try {
            hse.call(action, sse);
            SoapPrimitive primitive = (SoapPrimitive)sse.getResponse();
            Toast.makeText(getApplicationContext(),primitive.toString() , Toast.LENGTH_SHORT);
        } catch(IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
    }
}

onClick()そして、あなたはこのようにあなたにそれを呼ぶことができます

@Override
public void onClick(View v) {
    if(v.getId()==submit_btn.getId()) {
        new LongNetworkOperation.execute();
    }
}

また、ユーザーが長いバックグラウンドプロセスを認識できるように、ProgressDialogオンonPreExecute()と非表示を表示して非表示にすることをお勧めします。これは、長時間の操作に強く推奨されます。onPostExecute()

于 2013-01-16T15:40:14.853 に答える
2

ここでの問題は、別のスレッドで Web サービス呼び出し (または what-have-you) を行う必要があるということです。したがって、非常に簡単に言えば、Android でスレッド化を行う方法を調べる必要があります。残念ながら、別のスレッドでサービス呼び出しを行う必要があるため、これは少し面倒ですが、メイン スレッドで UI を更新する必要があります。通常、これにはスレッド間でデータを渡す必要があり、これにはハンドラーやその他の複雑さが伴います。幸いなことに、Android プラットフォームには、これを処理する Async Task が用意されています。これにより、この複雑さが軽減され、コードが煩雑になるのを防ぐことができます。

ネットワーク呼び出しをスレッド (または Android の非同期タスク) に移行するための便利なドキュメント

痛みのないスレッド化 (Android 開発者ドキュメントから) 非同期タスク (Android 開発者ドキュメントから) Android スレッド、ハンドラー、および AsyncTask – レスポンシブの設計のチュートリアル (Android 開発者ドキュメントから)

于 2013-01-15T17:57:30.913 に答える
1

NetworkOnMainThreadExceptionメイン スレッドでネットワーク リクエストを実行しないでください。. カスタムでこのソリューションを参照AsyncTaskするか、次のライブラリのいずれかを使用してください。

于 2013-01-15T17:59:39.457 に答える
1

あなたが抱えている問題は、あなたがしようとしているようなネットワーク操作は、メインの UI スレッドでは実行できませんし、実行すべきではありません。これを行うと、ANR (Android Not Responding)が発生します。これは、まさに今発生している種類のエラーです。あなたがしたいことは、コードを別のスレッドに移動するか、メイン UI スレッドのビューにアクセスできないメソッドをAsyncTask使用して、別のスレッドでバックグラウンドでこのアクションを実行するに移動することです。doInBackground()例えば、

private class ExampleOperation extends AsyncTask<String, Void, String> {

    public ExampleOperation() { //ctor }

    @Override
    protected void onPreExecute() {
        // things that you want to initialize and maybe show dialog to user.
    }

    @Override
    protected String doInBackground(String... params) {
       // this is where you perform that network related operation.  
    }

    @Override
    protected void onPostExecute(String result) {
       // this is where get the results from the network related task.
    }

    @Override
    protected void onProgressUpdate(Void... values) {
       // you can update your progressbar if any; otherwise omit method.
    }

}

あとは、使用したい場所で AsyncTask を呼び出すだけです。new ExampleOperation().execute();

于 2013-01-15T18:02:11.513 に答える