2013-06-14 2 views
0

В моем приложении я использую пользовательскую библиотеку для загрузки файлов svg, и процесс загрузки немного дорог, поэтому я пытаюсь переместить его в другой поток. И я получаю «CalledFromWrongThreadException». В соответствии с примером здесь: http://developer.android.com/guide/components/processes-and-threads.html#Threads все должно быть в порядке, но я все равно получаю сообщение об ошибке. Что мне не хватает?CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может коснуться его представлений

public class SinglePhraseFragment extends Fragment { 

View rootView; 
String imageFileName; 
int in_favorites, id; 
SpannableString phrase; 

@Override 
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    rootView = (ViewGroup) inflater.inflate(R.layout.single_phrase_layout, container, false); 


    new Thread(new Runnable() { 
     public void run() { 
      //loading svg file and converting it into drawable 
      SVG svg = null; 
      try { 
       final ImageView phraseImage = (ImageView) rootView.findViewById(R.id.phraseImage); 
       svg = SVGParser.getSVGFromAsset(getActivity().getAssets(), imageFileName); //loading svg file 
       final Drawable drawable = svg.createPictureDrawable(); //creating drawable from svg 
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
        phraseImage.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 

       //trying to set drawable to ImageView and getting error 
       phraseImage.post(new Runnable() { 
        public void run() { 
         phraseImage.setImageDrawable(drawable); 
        } 
       }); 
      } 
      catch (IOException e) {} 
      catch (SVGParseException e) {} 
     } 
    }).start(); 

    return rootView; 
} 

Так я редактировал код:

public class SinglePhraseFragment extends Fragment { 

View rootView; 
String imageFileName; 
int in_favorites, id; 
SpannableString phrase; 

@Override 
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    rootView = (ViewGroup) inflater.inflate(R.layout.single_phrase_layout, container, false); 


    new Thread(new Runnable() { 
     public void run() { 
      //loading svg file and converting it into drawable 
      SVG svg = null; 
      try { 
       final ImageView phraseImage = (ImageView) rootView.findViewById(R.id.phraseImage); 
       svg = SVGParser.getSVGFromAsset(getActivity().getAssets(), imageFileName); //loading svg file 
       final Drawable drawable = svg.createPictureDrawable(); //creating drawable from svg 
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
        phraseImage.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 

       //trying to set drawable to ImageView and getting error 
       getActivity().runOnUiThread(new Runnable() { 
        public void run() { 
         phraseImage.setImageDrawable(drawable); 
        } 
       }); 
      catch (IOException e) {Log.e("app", "IOException");} 
      catch (SVGParseException e) {Log.e("app", "SVGParseException");} 
     } 
    }).start(); 

    return rootView; 
} 

И это выход LogCat:

06-14 23:11:33.476: W/dalvikvm(8270): threadid=11: thread exiting with uncaught exception (group=0x40abb228) 
06-14 23:11:33.486: E/AndroidRuntime(8270): FATAL EXCEPTION: Thread-39961 
06-14 23:11:33.486: E/AndroidRuntime(8270): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
06-14 23:11:33.486: E/AndroidRuntime(8270):  at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4132) 
06-14 23:11:33.486: E/AndroidRuntime(8270):  at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:736) 
06-14 23:11:33.486: E/AndroidRuntime(8270):  at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:785) 
06-14 23:11:33.486: E/AndroidRuntime(8270):  at android.view.ViewGroup.invalidateChild(ViewGroup.java:4013) 
06-14 23:11:33.486: E/AndroidRuntime(8270):  at android.view.View.invalidate(View.java:8614) 
06-14 23:11:33.486: E/AndroidRuntime(8270):  at android.view.View.setLayerType(View.java:10128) 
06-14 23:11:33.486: E/AndroidRuntime(8270):  at com.potatopit.pick_app.SinglePhraseFragment$2.run(SinglePhraseFragment.java:74) 
06-14 23:11:33.486: E/AndroidRuntime(8270):  at java.lang.Thread.run(Thread.java:864) 
+0

Во-первых, никогда не помещайте пустые блоки обработчика исключений в свой код. Используйте 'Log.e()', чтобы записать их в LogCat, если ничего другого. Затем отправьте трассировку стека, показывающую вашу ошибку. – CommonsWare

+0

phraseImage.setImageDrawable (drawable); обновление ui из потока. обновите ui на потоке ui – Raghunandan

+0

, разместите свою трассировку стека. попробуйте использовать runOnUiThread, чтобы установить доступный для изображения. – Raghunandan

ответ

1

Как трассировки стека говорит вам, вы пытаетесь вызвать setLayerType() в фоновом потоке. Пожалуйста, сделайте это в основной прикладной нити, например, внутри Runnable, которую вы используете с runOnUiThread().

Кстати, вы можете использовать AsyncTask, для более чистого кода, а не ваш текущий Thread -and- runOnUiThread().

+0

Да. Это была сделка. Чувствует себя глупым прямо сейчас ... Большое спасибо) – kroart

+0

@kroart рассмотреть использование asynctask http://developer.android.com/reference/android/os/AsyncTask.html. – Raghunandan

+0

@ Рагхунандан да будет выглядеть – kroart

0

Кажется, вы обновляете интерфейс от фонового потока. Вам нужно обновить ui на главной теме.

Использование runOnUiThread

 getActivity().runOnUiThread(new Runnable(){ 
      public void run() 
      { 
       phraseImage.setImageDrawable(drawable);    
      } 
    }); 
+0

Я только что попробовал это. Ошибка все еще присутствует. Смотрите мой первый пост. – kroart

+0

@kroart, как предлагать commonsware, перемещать часть набора кода внутри runonuithread. но я бы предложил использовать asynctask для этой цели. нет путаницы – Raghunandan

Смежные вопросы

 Смежные вопросы