12

複数のHTTPクラス(HttpURLConnectionHTTPClientなど)を試しましたが、エミュレーターでは機能しません。それから私は私の電話でそれをテストすることに決めました、そしてそれはうまくいきました!

では、HTTPクラスが機能しない(ブラウザーは機能するが)というAndroidエミュレーターのこの奇妙な動作をどのように修正できますか?それらはアプリケーションをまったくクラッシュさせます。

これが私のコードです:

public static SimpleXML getResponse(String action, Map<String, String> params) {
     // Create a new HttpClient and Post Header
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(action);

    try {
        // Add your data
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(params.size());
        for(Map.Entry<String, String> heh : params.entrySet())
            nameValuePairs.add(new BasicNameValuePair(heh.getKey(), heh.getValue()));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);
        return SimpleXML.loadXml(response.getEntity().getContent());       

    } catch (ClientProtocolException e) {
        return null;
    } catch (IOException e) {
        return null;
    }   
}

LogCatログ:

06-30 22:07:28.972: E/AndroidRuntime(682): FATAL EXCEPTION: main
06-30 22:07:28.972: E/AndroidRuntime(682): android.os.NetworkOnMainThreadException
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.net.InetAddress.getAllByName(InetAddress.java:214)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-30 22:07:28.972: E/AndroidRuntime(682):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
06-30 22:07:28.972: E/AndroidRuntime(682):  at net.ekvium.air.API.getResponse(API.java:98)
06-30 22:07:28.972: E/AndroidRuntime(682):  at net.ekvium.air.MainActivity$1.onClick(MainActivity.java:62)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.view.View.performClick(View.java:4084)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.view.View$PerformClick.run(View.java:16966)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.os.Handler.handleCallback(Handler.java:615)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.os.Handler.dispatchMessage(Handler.java:92)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.os.Looper.loop(Looper.java:137)
06-30 22:07:28.972: E/AndroidRuntime(682):  at android.app.ActivityThread.main(ActivityThread.java:4745)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.lang.reflect.Method.invokeNative(Native Method)
06-30 22:07:28.972: E/AndroidRuntime(682):  at java.lang.reflect.Method.invoke(Method.java:511)
06-30 22:07:28.972: E/AndroidRuntime(682):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
06-30 22:07:28.972: E/AndroidRuntime(682):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
06-30 22:07:28.972: E/AndroidRuntime(682):  at dalvik.system.NativeStart.main(Native Method)
4

3 に答える 3

20

このAndroidのドキュメントを見ると、

NetworkOnMainThreadException:

アプリケーションがメインスレッドでネットワーク操作を実行しようとしたときにスローされる例外。

これは、HoneycombSDK以降を対象とするアプリケーションに対してのみスローされます。以前のSDKバージョンを対象とするアプリケーションは、メインのイベントループスレッドでネットワークを構築できますが、お勧めできません。

そのため、OSのバージョンによっては、UIスレッドでネットワークリクエストを行わないというポリシーが適用(例外スロー)される場合があります。これは、コードがエミュレーターではなくデバイスで機能する理由を説明している可能性があります(Androidのバージョンが異なる場合)。

を変更できますThreadPolicy。ただし、別の方法として、Androidドキュメントのステートメントをもう一度確認することをお勧めします。彼らはメインスレッドでネットワーク操作を実行することを強く思いとどまらせます、そして私は確かに彼らに同意します。

したがって、ポリシーを変更して合法にするのではなく、コードを変更getResponse()して、UIスレッドでメソッドが呼び出されないようにすることを検討してください。

通常、AsyncTaskを使用してバックグラウンドで作業を行います

于 2012-06-30T22:28:15.020 に答える
15

これは、メインスレッドでネットワークアクティビティを実行しようとしたために発生します。

私は同じ問題を抱えていました、それはしばらくの間機能しました、そして数週間の開発の後、それは機能しなくなりました。

私が見つけた解決策は、これらの行をに追加することでした

onCreate()

方法:

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

これがあなたにもうまくいくことを願っています

編集

賛成票が増えているので、何か付け加えたいと思います。これにより削除されますがNetworkingOnMainThreadExceptionこれは推奨される方法ではありません。

この例外には理由があります。ネットワークアクティビティには時間がかかる場合があり、UIの更新を担当するスレッドと同じメインスレッドでネットワークを実行すると、ネットワークが完了するまでスレッドがフリーズします(これはすべてのスレッドで発生しますが、専用で実行するとスレッド、それは大丈夫です)。Androidでは、UIスレッドが5秒間アクティブでない場合、Application is not responsive, Do you want to close it?ダイアログが表示されます。

これは、例外が防ぐようになったものです。私が提案したように、ポリシーを設定することは、例外を削除する一方で、物事を行うための間違った方法です。ネットワークアクションは、を使用するか、手動でAsyncTasknewを作成することにより、別のスレッドで実行する必要があります。これを実装する非常に簡単で簡単な方法であり、これが私がお勧めする方法です。ThreadAsyncTask

私の答えを使用するときは、この編集を考慮に入れてください。

乾杯

于 2012-06-30T22:14:42.757 に答える
0

次のコードを使用して、厳密モードを無効にします。

if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = 
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}

これはお勧めしませんAsyncTask。インターフェースを使用してください。

AsyncTaskのリンク

別の参考文献のリンク

于 2015-09-11T05:57:07.147 に答える