Android - ViewRootImpl $ CalledFromWrongThreadException

18

Я использовал этот , чтобы отображать изображения из Интернета но он вызывает ошибку, как показано ниже:
04-12 13: 45: 05.337: E / AndroidRuntime (27897): вызвано: android.view.ViewRootImpl $ CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений может коснуться его взглядов.

public class Order extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            new DownloadFilesTask().execute();       
        }    
        private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
            protected void onPostExecute(Void result) {
            }
             @Override
             protected Void doInBackground(Void... params) {
                 setContentView(R.layout.order);
                    ImageView imageView = (ImageView)findViewById(R.id.imgView);  
                    imageView.setImageDrawable(createDrawableFromURL("http://savagelook.com/misc/sl_drop2.png"));
                    return null;
             }          
        }     
        private Drawable createDrawableFromURL(String urlString) {
            Drawable image = null;
        try {
            URL url = new URL(urlString);
            InputStream is = (InputStream)url.getContent();
            image = Drawable.createFromStream(is, "src");
        } catch (MalformedURLException e) {
            image = null;
        } catch (IOException e) {
            image = null;
        } 
        return image;
        }

}
    
задан chinna_82 12.04.2012 в 08:14
источник
  • См. «Обработчики потоков» techotopia.com/index.php/... –  sαmosΛris 08.05.2013 в 18:08
  • В Mono используйте RunOnUiThread ... RunOnUiThread (() => {_tvMessage.Text="Загрузка ...";}); mono-for-android.1047100.n5.nabble.com/... –  sαmosΛris 08.05.2013 в 19:19

3 ответа

17

Поместите это в onCreate()

ImageView imageView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.order);
        imageView = (ImageView)findViewById(R.id.imgView);
        new DownloadFilesTask().execute();       
    } 

И ваш AsyncTask класс должен быть таким,

        private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
             Drawable drawable;

             @Override
             protected Void doInBackground(Void... params) {
             drawable = createDrawableFromURL(
                                   "http://savagelook.com/misc/sl_drop2.png");
              return null;
             }
             protected void onPostExecute(Void result) {
                    imageView.setImageDrawable(drawable);
            }          
        } 
    
ответ дан Lalit Poptani 12.04.2012 в 08:19
источник
  • imageView в ошибке onPostExecute throw. imageView не может быть разрешен –  chinna_82 12.04.2012 в 09:22
  • объявить ImageView как глобальный для активности –  Lalit Poptani 12.04.2012 в 09:34
  • Я думаю, что вы должны использовать обратный вызов обработчика Thread, который обращается к фоновому потоку с сообщением для основного потока пользовательского интерфейса для обновления пользовательского интерфейса (techotopia.com/index.php/...) –  sαmosΛris 08.05.2013 в 18:06
  • Наиболее важным моментом здесь является то, что представление (например, imageView) должно быть обновлено в методе onPostExecute, а не в doInBackground, что является основной причиной исключения. doInBackground выполняется в другом потоке, а onPostExecute выполняется в потоке вызывающего, который создает и выполняет экземпляр подкласса AsyncTask. –  Atharva 26.03.2014 в 12:29
24

У меня возникла такая же проблема, пытаясь изменить представление пользовательского интерфейса из c ++ с использованием JNI. Решением было использование

runOnUiThread(new Runnable() {
    public void run(){   
    }
});

runOnUiThread - это метод Activity, поэтому я должен сделать свой экземпляр активности public static, чтобы иметь возможность вызвать мой публичный статический метод, который позже вызывает JNI.

Надеюсь, что это поможет другим:)

PS: отсюда я узнаю, как использовать JNI Ссылка для моей игры для Android ранее сделанный с cocos2dx

    
ответ дан Ro Siade 24.09.2012 в 20:15
источник
  • Также: передать переменные сделать их окончательными, см. stackoverflow.com/a/7762412/956397 –  PiTheNumber 30.05.2016 в 11:45
2

Я думаю, что эта строка вызывает ошибку.

  imageView.setImageDrawable(createDrawableFromURL("http://savagelook.com/misc/sl_drop2.png"));

и ошибка объясняет, почему это так.

     Only the original thread that created a view hierarchy can touch its views.

эта ошибка вызвана тем, что вы пытаетесь изменить пользовательский интерфейс на mainthread из какого-то другого потока. Здесь doInBackground в вашем случае ...

    
ответ дан 5hssba 12.04.2012 в 08:24
источник
  • как я могу это решить ..? –  chinna_82 12.04.2012 в 09:25
  • , как сказал Лалит Поптани ... его код решает .. и для imageView не может быть разрешено. declare ImageView imageView; как это до oncreate .. так что он доступен для всех функций .. в классе деятельности .. –  5hssba 12.04.2012 в 09:27