web-dev-qa-db-ja.com

DefaultHttpClientからAndroidHttpClient

コードに問題があり、助けが欲しいと思っていました。私は最初にこのコードを使用していました:

        new DefaultHttpClient().execute(new HttpGet(linkk)).getEntity().writeTo(
           new FileOutputStream(f));

そして、Android 2.3では正常に動作しますが、4.0では動作しません。いくつかの調査の後、AndroidHttpClientを使用する方が良いと聞きました。私は自分のコードを正しく修正したかどうか、そしてインターネット上のAndroidhttpClientに関する例があまり多くないかどうかわからないということです。

調整されたコードは次のとおりです。

    AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
    HttpGet request = new HttpGet(linkk);   
    HttpResponse response = client.execute(request); //here is where the exception is thrown    
    response.getEntity().writeTo(new FileOutputStream(f));

これはlogcatが示すものです:

     01-03 01:32:11.950: W/dalvikvm(17991): threadid=1: thread exiting with uncaught exception (group=0x40a2e1f8)
     01-03 01:32:11.986: E/AndroidRuntime(17991): FATAL EXCEPTION: main
     01-03 01:32:11.986: E/AndroidRuntime(17991): Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lacra.fbirthdays/com.lacra.fbirthdays.ListV}: Android.os.NetworkOnMainThreadException
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:1956)
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:1981)
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Android.app.ActivityThread.access$600(ActivityThread.Java:123)
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1147)
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Android.os.Handler.dispatchMessage(Handler.Java:99)
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Android.os.Looper.loop(Looper.Java:137)
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Android.app.ActivityThread.main(ActivityThread.Java:4424)
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Java.lang.reflect.Method.invokeNative(Native Method)
     01-03 01:32:11.986: E/AndroidRuntime(17991):   at Java.lang.reflect.Method.invoke(Method.Java:511)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:784)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:551)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at dalvik.system.NativeStart.main(Native Method)
    01-03 01:32:11.986: E/AndroidRuntime(17991): Caused by: Android.os.NetworkOnMainThreadException
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at Android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.Java:1099)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at Java.net.InetAddress.lookupHostByName(InetAddress.Java:391)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at Java.net.InetAddress.getAllByNameImpl(InetAddress.Java:242)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at Java.net.InetAddress.getAllByName(InetAddress.Java:220)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at org.Apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.Java:137)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at org.Apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.Java:164)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at org.Apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.Java:119)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at org.Apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.Java:360)
    01-03 01:32:11.986: E/AndroidRuntime(17991):    at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:555)
26
Lara

StrictMode.ThreadPolicy は、APIレベル9以降に導入され、デフォルトのスレッドポリシーはAPIレベル11以降に変更されたため、ネットワーク操作(HttpClientおよびHttpUrlConnectionを含む)がUIスレッドで実行されることを許可しません。これを行うと、NetworkOnMainThreadExceptionが発生します。

この制限は、次を使用して変更できます。

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

上記のコードをメインアクティビティのonCreate()メソッドに追加します。

また、ネットワークオペレーションをUIスレッドから移動することを常にお勧めします。たとえば、 AsyncTask。

この助けを願っています。

72
yorkw

ネットワーク要求がUIスレッドをブロックしないように、 AsyncTask を使用します。 NetworkOnMainThreadException はAPIバージョン11以降に導入されたため、3.0以降のみが表示されます。

private class NetworkTask extends AsyncTask<String, Void, HttpResponse> {
    @Override
    protected HttpResponse doInBackground(String... params) {
        String link = params[0];
        HttpGet request = new HttpGet(link);
        AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
        try {
            return client.execute(request);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
        client.close();
    }
    }

    @Override
    protected void onPostExecute(HttpResponse result) {
        //Do something with result
        if (result != null)
            result.getEntity().writeTo(new FileOutputStream(f));
    }
}

このスレッドを単純に呼び出すには、これを行います。

new NetworkTask().execute(linkk);

Android開発者サイトに書かれたこの記事 をご覧ください。アプリの記述方法について詳しく説明していますスレッドを処理します。

32
Stefan Bossbaly