Исключение networkOnMainThread для Android

Я пытаюсь получить доступ к серверу, чтобы получить строку JSON. Но видимо в Ice Cream Sandwich нельзя делать сетевые операции в основном потоке, а класс AsyncTask меня смущает и не работает. Вот что у меня есть до сих пор:

//up in main code
Void blah = null;
URI uri = "kubie.dyndns-home.com/R2Bar2/ingredients.php";
new DownloadFilesTask().execute(uri , blah, blah);


private class DownloadFilesTask extends AsyncTask<URI, Void, Void> {
        protected Void doInBackground(URI... uri) {
            HttpClient client = new DefaultHttpClient();
            String json = "";
            int duration = Toast.LENGTH_SHORT;
            try {
                HttpResponse response = null;
                BufferedReader rd = null;
                String line = "";
                HttpGet request = new HttpGet(uri);
            } catch (URISyntaxException e1) {

            }
return null;
        }

        protected void onProgressUpdate(Integer... progress) {

        }

        protected void onPostExecute(Long result) {

        }

Ему не нравится мой HttpGet request = new HttpGet(uri). Он говорит изменить uri на URI, но это уже так! Я попытался изменить все параметры на Void, но мое приложение просто принудительно закрывается.

Кто-нибудь знает, как это сделать?


person Nelson.b.austin    schedule 15.03.2012    source источник


Ответы (2)


Попробуйте этот пример:

    public class Test_anroidActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String uri = new String("http://kubie.dyndns-home.com/R2Bar2/ingredients.php");
        new DownloadFilesTask().execute(uri , null, null);
    }
    private class DownloadFilesTask extends AsyncTask<String, Void, String> {
        protected String doInBackground(String... urls) {
            HttpClient client = new DefaultHttpClient();
            String json = "";
            try {
                String line = "";
                HttpGet request = new HttpGet(urls[0]);
                HttpResponse response = client.execute(request);
                BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                while ((line = rd.readLine()) != null) {
                    json += line + System.getProperty("line.separator");
                }
            } catch (IllegalArgumentException e1) {
                e1.printStackTrace();
            } catch (IOException e2) {
                e2.printStackTrace();
            }
            return json;
        }

        protected void onProgressUpdate(Void... progress) {

        }

        protected void onPostExecute(String result) {

        }
    }
}

Последнее, ваш сервер возвращает php-файл, это правильное поведение?

person Roman Truba    schedule 16.03.2012
comment
ДА! Большое спасибо! Я думаю, что то, что не работало, — это уведомление Toast. Мне пришлось вернуть свою строку, а затем декодировать JSON. Спасибо еще раз! - person Nelson.b.austin; 16.03.2012

Но видимо в Ice Cream Sandwich нельзя делать сетевые операции в основном потоке

Вы можете, но это выдаст вам предупреждение в LogCat. Кроме того, вы не должны выполнять сетевые операции в основном потоке приложения, так как это приведет к зависанию вашего пользовательского интерфейса и, возможно, к появлению диалогового окна "Приложение не отвечает" (ANR).

но класс AsyncTask меня смущает и не работает

В вашем текущем коде вы фактически не выполняете запрос HttpGet.

Ему не нравится мой запрос HttpGet = new HttpGet(uri) Он говорит изменить uri на URI, но это уже так!

Нет это не так.

... после URI в объявлении doInBackground() означает, что этот метод принимает переменное количество аргументов. Ваш параметр uri, по сути, является параметром URI[]. Если вы звоните execute() только с одним URI, вы получаете URI через uri[0], а не uri.

person CommonsWare    schedule 15.03.2012
comment
Ой, забыл добавить: 'try { response = client.execute(request); } catch (ClientProtocolException e) {' Но он все равно принудительно закрывается. Нужны ли мне какие-либо параметры для класса? Могу ли я просто создать URI в методе doInBackground()? - person Nelson.b.austin; 16.03.2012