在android

时间:2015-10-03 16:18:48

标签: java android handler behavior

我刚刚编写了一个代码,它添加了几个视图,每个视图使用一个处理程序。这些是使用for循环添加的。这些添加正确。然后我尝试在for循环之后添加一个按钮而不使用处理程序。这次按钮显示在布局的顶部,即在for循环中添加的项目之前。如果我使用处理程序添加按钮,则不会发生这种情况。

因此,如果我在循环后使用以下代码和处理程序,那么按钮将添加到布局的底部:

 private void fillFeedWithData(final List<ParseObject> feedObjectList) {

    LayoutInflater inflaterOfFeedItem = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    for (int i = 0; i < feedObjectList.size(); i++) {

        final String jokeTitle = feedObjectList.get(i).getString("content");

        final View cvFeedItem = inflaterOfFeedItem.inflate(R.layout.feed_item_theme_card, null);

        final TextView tvJoke = (TextView) cvFeedItem.findViewById(R.id.tvFeedJoke);

        Handler h2 = new Handler();
        Runnable update2 = new Runnable() {
            public void run() {
                tvJoke.setText(jokeTitle);
                llFragmentFeedParent.addView(cvFeedItem);
    // llFragmentFeedParent is acquired in OnCreate() method
            }
        };
        h2.post(update2);
    }


    final Button bNext = new Button(this);
    bNext.setText("Next >");
    bNext.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

    Handler h3 = new Handler();
    Runnable update3 = new Runnable() {
        public void run() {
            llFragmentFeedParent.addView(bNext);
        }
    };
    h3.post(update3);
}

如果我在循环后使用了以下代码,那么按钮将添加到布局的顶部:

    Button bNext = new Button(this);
    bNext.setText("Next >");
    bNext.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    llFragmentFeedParent.addView(bNext);

所以现在我的应用程序正在与处理程序一起工作,但我担心为什么会发生这种情况。我认为处理程序正在混合执行的时间/顺序?如果我继续使用逻辑,那么按钮可能会在慢速移动电话中显示在循环中,甚至在循环中添加的项目之间?

1 个答案:

答案 0 :(得分:2)

我不确定你为什么要这样做,但要回答你的问题。处理程序将Runnables发布到按顺序运行的队列中(假设您不使用postDelayed)。它们最终运行 意味着它们执行时完全取决于发布了多少其他Runnables以及这些Runnables执行所需的时间。

处理程序实际上共享一个创建它们的Looper线程(在本例中是主UI Looper线程),因此无论您使用多少个Handler引用,它们都将在同一个线程中发布。同样,您可以传入另一个线程的Looper对象,以便Runnables将在该线程上运行。

在这种情况下,当您添加一个没有处理程序的按钮时,您将在其他处理程序执行之前将其添加到视图 now 。当您在另一个也在UI线程上创建的处理程序中发布时,它会在您发布的第一个处理程序之后将Runnable发布到队列中。所以他们有效地顺序运行。

编辑:

同样在这种情况下,我会完全抛弃Handler机制,只需将您要添加的所有视图添加到List中,然后将它们添加到集合中。你每次传递都会发布一个新的Runnable,它将为布局添加一个新视图,这将触发布局传递,这将触发绘制传递。最好一次性添加它们。