コードに問題があり、助けが欲しいと思っていました。私は最初にこのコードを使用していました:
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)
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。
この助けを願っています。
ネットワーク要求が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開発者サイトに書かれたこの記事 をご覧ください。アプリの記述方法について詳しく説明していますスレッドを処理します。