Android - ViewRootImpl$CalledFromWrongThreadException

喜欢而已 提交于 2019-11-26 11:29:16

问题


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

}

回答1:


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



回答2:


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




回答3:


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...




回答4:


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 

  }
});

@canerkaseler



来源:https://stackoverflow.com/questions/10118301/android-viewrootimplcalledfromwrongthreadexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!