HonyComb и DefaultHttpClient
В моем коде у меня есть это
Log.d("WFlog (executeRequest)", request.toString()) ;
httpResponse = client.execute(request);
Log.d("WFlog (execute)", request.toString()) ;
запуск приложения с использованием Android 2.2 идет хорошо, и в logcat я вижу обе строки журнала.
Теперь запуск приложения с использованием HonyComb для одного и того же фрагмента кода кажется, что я никогда не получаю client.execute правильно. Последняя строка журнала, которую я получаю, имеет "WFlog (executeRequest)".
После этого я вижу следующее:
01-27 21:54:45.169: WARN/System.err(390): android.os.NetworkOnMainThreadException
01-27 21:54:45.196: WARN/System.err(390): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1069)
01-27 21:54:45.196: WARN/System.err(390): at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:368)
01-27 21:54:45.205: WARN/System.err(390): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:208)
01-27 21:54:45.215: WARN/System.err(390): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:431)
01-27 21:54:45.237: WARN/System.err(390): at java.net.Socket.connect(Socket.java:901)
Любая идея, что я должен искать?
Ответы
Ответ 1
Существуют новые политики, которые позволяют разработчикам приложений и операционных систем устанавливать ожидания производительности для выполнения кода на определенных потоках. Вы пытались вызвать блокировку сети api в потоке ui вашего приложения. Google внедрила систему, которая позволяет вам знать, что это плохая идея, и вы можете решить эту проблему, выполнив ваш запрос в отдельном потоке или asyncTask.
Прочитайте этот блог. Вы можете найти информацию о работе с асинхронными/многопоточными приложениями по всему SO и Google.
Ответ 2
Спасибо, Ник. Это сработало для меня. Для цели я просто устанавливаю политику потока по умолчанию, делая это
*ThreadPolicy tp = ThreadPolicy.LAX;
StrictMode.setThreadPolicy(tp);*
Это необходимо удалить для окончательной версии.
Ответ 3
абхинальное предложение, написанное как отражение, поэтому код также работает с более старыми версиями API:
try {
Class strictModeClass=Class.forName("android.os.StrictMode");
Class strictModeThreadPolicyClass=Class.forName("android.os.StrictMode$ThreadPolicy");
Object laxPolicy = strictModeThreadPolicyClass.getField("LAX").get(null);
Method method_setThreadPolicy = strictModeClass.getMethod(
"setThreadPolicy", strictModeThreadPolicyClass );
method_setThreadPolicy.invoke(null,laxPolicy);
} catch (Exception e) {
}
Да, этот должен быть удален для окончательной версии.
Ответ 4
Я использовал asynctask, видел его в других потоках, и он работал нормально.... Я создаю подкласс, где я хотел вызвать сетевое соединение. я не знаю, если это лучший способ, но этот код работал у меня....
public miclase{
public boolean comprobarMP3(int canal){
boolean retorno=true;
//This commented Code is what it was NOT working
//swr= new ServicioWebRest();
//contenido=swr.obtieneContenido(Channels.getInstance().getChannel().get(canal).getId());
try{
//this.get() was important, i had troubles in recovering the objet, .get() solved it
contenido=new getContenidoAsync().execute(canal).get();
}catch(Exception e){
contenido=null;
}
}
//Clase interna para acceder a los webservice de un modo asincrono en otro hilo
//Desde el sdk 11, las politicas de seguridad de android no permiten acceder a internet desde el hilo principal
public class getContenidoAsync extends AsyncTask<Integer, Void, Contenido>{
Contenido c=new Contenido();
@Override
protected Contenido doInBackground(Integer... urls) {
//aqui el codigo q sea, yo llamo a este que llama a otra clase que es el q llama a http
return new ServicioWebRest().obtieneContenido(Channels.getInstance().getChannel().get(urls[0]).getId());
}
@Override
protected void onPostExecute(Contenido result) {
c=result;
}
}
}