3

我在这里有一个简单的程序。当您点击“+”时,它会在列表中添加一个新数字。该列表在屏幕上表示为LinearLayout包含每个数字标记的按钮。每次按“+”时,我都会清除LinearLayout,然后将每个按钮添加到片段事务并提交。

所以如果你在程序启动后按“+”3次,它通常看起来像这样:

没有损坏

问题是有时似乎下一个片段事务与前一个事务同时运行。如果你按“+”太快,你会得到一个数字的多个按钮。这是它的样子:

破碎的

这是我的代码的主要部分:

package com.example.kore.ui;

import java.util.LinkedList;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import com.example.kore.R;

public class CodeEditor extends Fragment {
  private LinearLayout fields;
  private final LinkedList<String> list = new LinkedList<String>();
  private int x;
  private boolean sleep;
  private int inits;

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.code_editor, container, false);
    fields = (LinearLayout) v.findViewById(R.id.layout_fields);
    ((Button) v.findViewById(R.id.button_clear))
        .setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View v) {
            list.clear();
            init();
          }
        });
    ((Button) v.findViewById(R.id.button_new_field))
        .setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            list.add("" + x++);
            init();
          }
        });
    init();
    sleep = true;
    return v;
  }

  private void init() {
    String prefix = "" + inits++;
    fields.removeAllViews();
    FragmentTransaction fragmentTransaction =
        getFragmentManager().beginTransaction();
    for (String s : list) {
      Field f = new Field();
      Bundle b = new Bundle();
      b.putString("X", prefix + " - " + s);
      f.setArguments(b);
      fragmentTransaction.add(R.id.layout_fields, f);
    }
    Log.d("WTF", prefix + " zzzz..");
    if (sleep) {
      try {
        Thread.sleep(2000);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    }
    sleep = !sleep;
    fragmentTransaction.commit();

  }

}

我把这个 sleep 每隔一秒init调用一次,它让它更容易重现。

Field只是一个带有按钮的片段。主要活动只是启动CodeEditor片段。

我刚开始编写android。也许有一些我不明白的基础知识。也许事务意味着某种并发,尽管据我所知,任何地方都不应该有并发。这种类似比赛条件的行为怎么会发生?我究竟做错了什么?我将按钮包裹在片段中,这些片段被添加到CodeEditor片段中,因为我的真实程序更复杂(这是一个精简的示例),所以嵌套片段有点意义。

完整的代码在这里

4

0 回答 0