Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - ViewRootImpl$CalledFromWrongThreadException

I was using this, to DISPLAY IMAGES FROM THE INTERNET but it throws an error as below:
04-12 13:45:05.337: E/AndroidRuntime(27897): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

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

}
like image 247
chinna_82 Avatar asked Apr 12 '12 06:04

chinna_82


4 Answers

I got the same problem trying to change UI view from c++ using JNI. The solution was use

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

runOnUiThread is an Activity method so I have to make my activity instance public static to be able to call on my public static method who later call from JNI.

Hope this help others :)

PS: from here I learn how to use JNI http://www.cocos2d-x.org/projects/cocos2d-x/wiki/How_to_use_jni for my android game previously made with cocos2dx

like image 80
Ro Siade Avatar answered Oct 23 '22 01:10

Ro Siade


Put this in 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();       
    } 

And your AsyncTask class should be like this,

        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);
            }          
        } 
like image 21
Lalit Poptani Avatar answered Oct 23 '22 02:10

Lalit Poptani


I think this line is causing the error..

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

and the error explains why it is so..

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

this error is caused because you are trying to change the User Interface on mainthread from some other thread.. here doInBackground in your case...

like image 22
5hssba Avatar answered Oct 23 '22 02:10

5hssba


If you would like to do this job in fragment, you should call UI thread from activity in fragment.

getActivity().runOnUiThread(new Runnable() {
  public void run(){

    ... //your job 

  }
});
like image 1
DevPolarBear Avatar answered Oct 23 '22 01:10

DevPolarBear