在我的应用程序中,我使用自定义库来加载svg文件,并且加载过程有点贵,所以我试图将其移动到另一个线程中。我得到“CalledFromWrongThreadException”。根据这里的例子:http://developer.android.com/guide/components/processes-and-threads.html#Threads一切都必须正常,但我仍然收到错误。我缺少什么?
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 :(得分:1)
当堆栈跟踪告诉您时,您正试图在后台线程上调用setLayerType()
。请在主应用程序主题上执行此操作,例如您在Runnable
使用的runOnUiThread()
内。
顺便说一句,您可能希望使用AsyncTask
来获得更清晰的代码,而不是当前的Thread
- 和 - runOnUiThread()
实施。
答案 1 :(得分:0)
您似乎正在从后台线程更新ui。你需要在主ui线程上更新ui。
使用runOnUiThread
getActivity().runOnUiThread(new Runnable(){
public void run()
{
phraseImage.setImageDrawable(drawable);
}
});