CalledFromWrongThreadException意外发生

时间:2013-09-05 22:56:55

标签: android

我正在做的事情的简要说明:我的FragmentActivity通过ViewPager托管4个碎片,这些碎片是在我的课程中创建的,扩展了Fragment

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = null;
    switch (mPage) {

    case 1:

        view = inflater.inflate(R.layout.frag1,
                container, false);
        initFrag1(view);
        break;

    // ....... and so on

    }

    return view;
}

onCreateView()方法中,我根据页面(片段)初始化数据。每个片段都有相当复杂的布局,有很多TextViews。当用户点击上一个FragmentActivity中的ListItem时会启动Activity,并且在FragmentActivity开始之前会有大约0.5-1秒的延迟。我的考虑是延迟是由初始化和设置吨TextViews引起的,所以我试图在AsyncTask中做所有这些事情:

    @Override
protected Void doInBackground(Void... params) {

    DecimalFormat df = new DecimalFormat("#0.00");

    for (int i = 0; i < FirstTextViewArray.length; i++) {
        tmp = (TextView) v.findViewById(FirstTextViewArray[i]);
        tmp.setText("test " + String.valueOf(i));
    }
    for (int i = 0; i < SecondTextViewArray.length; i++) {
        tmp = (TextView) v.findViewById(SecondTextViewArray[i]);
        tmp.setText(df.format((SomeClass
                .getSomeFloatArray(Constants.tmpObject.getSomeInt())[i]));


    }
    return null;

}

所以基本上我只是将TextViews作为Arrays传递给View并将AsyncTask传递给构造函数中的Fragments,然后在循环内初始化并设置它们。 / p>

当我在应用程序崩溃的CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views 之间滑动时,它有时会起作用(比如十分之一):

Exception

我知道Views的意思,但问题是:为什么会意外发生?

第二个问题:我认为初始化并在背景中设置Activity's不是要走的路。那我怎样才能避免{{1}}开始时的延迟?

2 个答案:

答案 0 :(得分:1)

使用AsyncTask.onProgressUpdate方法安全地更新UI线程上的UI。这是一个粗略的大纲:

new AsyncTask<Void, Object, Void>() {

    DecimalFormat df = new DecimalFormat("#0.00");

    @Override
    protected void onProgressUpdate(Object... values) {
        String label = (String) values[0];
        int viewId = (Integer) values[1];
        TextView tv = (TextView) v.findViewById(viewId);
        tv.setText(label);
    }

    @Override
    protected Void doInBackground(Void... params) {

        for (int i = 0; i < FirstTextViewArray.length; i++) {
            publishProgress("test " + String.valueOf(i), FirstTextViewArray[i]);
        }
        for (int i = 0; i < SecondTextViewArray.length; i++) {
            publishProgress(
                    df.format((SomeClass.getSomeFloatArray(Constants.tmpObject.getSomeInt())[i])),
                    SecondTextViewArray[i]);


        }
        return null;
    }
}.execute();

答案 1 :(得分:0)

只有主线程可以使用视图,这就是您收到此错误的原因。 你应该使用这个帖子:

getActivity().runOnUiThread(new Runnable() {
     public void run() {
          //stuff that updates your views
          DecimalFormat df = new DecimalFormat("#0.00");

          for (int i = 0; i < FirstTextViewArray.length; i++) {
              tmp = (TextView) v.findViewById(FirstTextViewArray[i]);
              tmp.setText("test " + String.valueOf(i));
          }
          for (int i = 0; i < SecondTextViewArray.length; i++) {
              tmp = (TextView) v.findViewById(SecondTextViewArray[i]);
              tmp.setText(df.format((SomeClass.getSomeFloatArray(Constants.tmpObject.getSomeInt())[i]));

          }
    }
});

所以