0

我制作了一个应该编译 TextView 的 AsyncTask。这是对我所做工作的简短回顾。我删除了很多行,所以我希望我没有忘记任何东西。

public class MyClass extends RelativeLayout {
        private TextView messageTextView;


    public MyClass(Context context) {
        super(context);
        init(context); }
    public MyClass(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context); }
    public MyClass(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context); }


    private void init(Context context) {
        createLayoutContent();
                run();
    }

    private void createLayoutContent (Context context) {
        this.setLayoutParams(new RelativeLayout.LayoutParams (RelativeLayout.LayoutParams.MATCH_PARENT, 0));

        messageView = new TextView(context);
        messageView.setText("test");
        this.addView(messageView);
    }

    private void start() {
        new AsyncTask<Void, String, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    String s_message = "test2";
                    messageView.setText(s_message);    **// HERE IS WHERE THE ERROR IS //**
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }.execute();

    }

}

在此之后,我将对象直接放入布局中:

    <<...>MyClass
        android:id="@+id/test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
    />

现在的问题是,在某些应用程序上,这非常有效。一旦 Activity 运行,setContentView() 就会创建 ui 对象,一切都很好。在其他应用程序上,我不断收到一条错误消息,提示“只有创建视图层次结构的原始线程才能接触其视图。

我收到此错误,但我不明白为什么在某些应用程序上它可以正常工作......更奇怪的是,曾经发生过一次通常会出错的应用程序突然开始工作,然后在两个之后又回到错误正确运行!!

这完全奇怪。

我知道可能细节不足以检测错误,所以请原谅我,但我检查了我能想到的所有细节,我找不到它何时有效与何时无效之间的显着差异。也许更多专家的眼睛可以检测到一些东西,解释一些东西或者建议我在哪里调试。有人能帮我吗?

非常感谢你。

4

1 回答 1

2

我不确定,为什么它有时会起作用。但它应该每次都失败。如果 Android 系统决定在 UI 线程中运行您的后台线程代码,它可能会起作用。

这是解决您问题的方法:将“触摸视图”的东西移到onPostExcution()or onProgressUpdate()。UI 意味着只能从 UI 线程中触摸。AsyncTask 有助于非常方便地做到这一点。除了在 UI 线程上运行的所有AsyncTask's方法。doInBackground()

所以,永远不要Views直接从doInBackground().

private void start() {
    new AsyncTask<Void, String, String>() {
        @Override
        protected String doInBackground(Void... params) {
            try {
                String s_message = "test2";
                return s_message;
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            messageView.setText(s);
        }
    }.execute();
}
于 2013-10-06T22:51:41.290 回答