Ошибка при заполнении Spinner в AsyncTask

Ответить
justikim
Сообщения: 6
Зарегистрирован: 24 мар 2015, 20:10

Ошибка при заполнении Spinner в AsyncTask

Сообщение justikim » 17 май 2015, 01:12

Добрый день, ситуация следующая. Есть AsyncTask, который делает запрос к серверу и получает ответ в ввиде JSON. Мне нужно распарсить JSON и на основе полученного массива заполнить Spinner. С парсингом проблем нет, но при создании спиннера вылетает RuntimeException.
Код:

Код: Выделить всё

class LoadAllProducts extends AsyncTask<String, String, String>{
        // сначала показываем progress dialog
        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            pDialog = new ProgressDialog(NewOrderActivity.this);
            pDialog.setMessage("Идет загрузка продуктов. Пожалуйста ждите...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }

        // Получаем продукты
        protected  String doInBackground(String... args){
            ArrayList<String> list = new ArrayList<String>();
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);
            Log.d("All Products: ",json.toString());
            try{
                //проверка SUCCESS TAG
                int success = json.getInt(TAG_SUCCESS);
                if(success == 1){
                    products = json.getJSONArray(TAG_PRODUCTS);
                    for(int i = 0; i< products.length(); i++){
                        JSONObject c = products.getJSONObject(i);
                        String name = c.getString(TAG_NAME);
                        list.add(name);
                    }
                    String[] arr;
                    arr = list.toArray(new String[list.size()]);
                    ArrayAdapter<String> adapter = new ArrayAdapter<String>(NewOrderActivity.this, android.R.layout.simple_spinner_item, arr);
                    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                    Spinner spinner = (Spinner) findViewById(R.id.inputOrderName);
                    spinner.setAdapter(adapter);
                    spinner.setPrompt("Title");
                    spinner.setSelection(2);

                } else{  // Продукт не найден. Запустим создание нового продукта
                    Intent i = new Intent(getApplicationContext(), NewProductActivity.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(i);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(String file_url){
            pDialog.dismiss();
        }
    }
}
Ошибка:

Код: Выделить всё

java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)
            at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
     Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4607)
            at android.view.ViewRootImpl.focusableViewAvailable(ViewRootImpl.java:2574)
            at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:604)
            at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:604)
            at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:604)
            at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:604)
            at android.view.View.setFlags(View.java:8290)
            at android.view.View.setFocusable(View.java:5565)
            at android.widget.AdapterView.checkFocus(AdapterView.java:718)
            at android.widget.AbsSpinner.setAdapter(AbsSpinner.java:115)
            at android.widget.Spinner.setAdapter(Spinner.java:371)
            at com.kim.kursach.NewOrderActivity$LoadAllProducts.doInBackground(NewOrderActivity.java:179)
            at com.kim.kursach.NewOrderActivity$LoadAllProducts.doInBackground(NewOrderActivity.java:146)
            at android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)

Ошибка на строке spinner.setAdapter(adapter);

Как это можно исправить? Может заполнять спиннер не в параллельном потоке а в основном? как тогда передать в основной поток строку из AsyncTask?

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Ошибка при заполнении Spinner в AsyncTask

Сообщение Foenix » 17 май 2015, 15:33

Например через handler
И ещё способы есть, читай уроки
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Ошибка при заполнении Spinner в AsyncTask

Сообщение doter.ua » 17 май 2015, 15:42

В доИнБГ собираешь инфу, в онПост отправляешь в основной поток (там, где запускал аТаск) и скармливаешь спиннеру.
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

justikim
Сообщения: 6
Зарегистрирован: 24 мар 2015, 20:10

Re: Ошибка при заполнении Spinner в AsyncTask

Сообщение justikim » 17 май 2015, 15:51

doter.ua писал(а):В доИнБГ собираешь инфу, в онПост отправляешь в основной поток (там, где запускал аТаск) и скармливаешь спиннеру.
Из ДоИнБг в онПост можно передать методом get, на сколько я знаю. а как передать из онПост в основной поток?

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Ошибка при заполнении Spinner в AsyncTask

Сообщение doter.ua » 17 май 2015, 16:04

justikim писал(а):
doter.ua писал(а):В доИнБГ собираешь инфу, в онПост отправляешь в основной поток (там, где запускал аТаск) и скармливаешь спиннеру.
Из ДоИнБг в онПост можно передать методом get, на сколько я знаю. а как передать из онПост в основной поток?
Из дуИнБГ передается return-м. Смотри инфу пр оасинктаск.
онПост по дефолту в основном потоке, вызови в нем свой метод из активити или сделай всю работу сразу в онПост.
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

justikim
Сообщения: 6
Зарегистрирован: 24 мар 2015, 20:10

Re: Ошибка при заполнении Spinner в AsyncTask

Сообщение justikim » 17 май 2015, 19:20

doter.ua писал(а):
justikim писал(а):
doter.ua писал(а):В доИнБГ собираешь инфу, в онПост отправляешь в основной поток (там, где запускал аТаск) и скармливаешь спиннеру.
Из ДоИнБг в онПост можно передать методом get, на сколько я знаю. а как передать из онПост в основной поток?
Из дуИнБГ передается return-м. Смотри инфу пр оасинктаск.
онПост по дефолту в основном потоке, вызови в нем свой метод из активити или сделай всю работу сразу в онПост.

Спасибо, такое решение помогло.

Код: Выделить всё

 class LoadAllProducts extends AsyncTask<String, String[], String[]>{ 
        // сначала показываем progress dialog 
        @Override 
        protected void onPreExecute(){ 
            super.onPreExecute(); 
            pDialog = new ProgressDialog(NewOrderActivity.this); 
            pDialog.setMessage("Идет загрузка продуктов. Пожалуйста ждите..."); 
            pDialog.setIndeterminate(false); 
            pDialog.setCancelable(false); 
            pDialog.show(); 
        } 
 
        // Получаем продукты 
        protected  String[] doInBackground(String... args){ 
 
            ArrayList<String> list = new ArrayList<String>(); 
            List<NameValuePair> params = new ArrayList<NameValuePair>(); 
            JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params); 
            Log.d("All Products: ",json.toString()); 
            try{ 
                //проверка SUCCESS TAG 
                int success = json.getInt(TAG_SUCCESS); 
                if(success == 1){ 
                    products = json.getJSONArray(TAG_PRODUCTS); 
                    for(int i = 0; i< products.length(); i++){ 
                        JSONObject c = products.getJSONObject(i); 
                        String name = c.getString(TAG_NAME); 
                        list.add(name); 
                    } 
 
                    arr = list.toArray(new String[list.size()]); 
 
 
                } 
            } catch (JSONException e) { 
                e.printStackTrace(); 
            } 
            return arr; 
        } 
 
        protected void onPostExecute(String[] array){ 
            super.onPostExecute(array); 
            pDialog.dismiss(); 
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(NewOrderActivity.this, android.R.layout.simple_spinner_item, array); 
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
            spinner.setAdapter(adapter); 
            spinner.setPrompt("Title"); 
            spinner.setSelection(2); 
 
        } 
    } 

Ответить