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;
        }       
    }
}