3

ここに簡単なプログラムがあります。「+」を押すと、リストに新しい番号が追加されます。LinearLayoutリストは、各番号でラベル付けされたボタンを含むものとして画面に表示されます。「+」を押すたびに、をクリアしてLinearLayoutから、各ボタンをフラグメントトランザクションに追加してコミットします。

したがって、プログラムの開始後に「+」を3回押すと、通常は次のようになります。

壊れていません

問題は、次のフラグメントトランザクションが前のフラグメントトランザクションと同時に実行されているように見える場合があることです。「+」を押すのが速すぎると、1つの番号に対して複数のボタンが表示されます。これはどのように見えるかです:

壊れた

これが私のコードの主要部分です:

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();

  }

}

毎秒この睡眠をとるinitと呼ばれるので、再現しやすくなります。

Fieldボタンが入った単なる断片です。メインアクティビティは単にCodeEditorフラグメントを開始します。

私はちょうどアンドロイドのプログラミングを始めました。多分私が理解していないいくつかの基本があります。おそらく、トランザクションはある種の並行性を意味しますが、私が知る限り、どこにも並行性があってはなりません。この競合状態のような動作はどのように発生する可能性がありますか?私は何が間違っているのですか?私のボタンはフラグメントでラップされており、CodeEditorフラグメントに追加されています。これは、実際のプログラムがより複雑であるため(これは縮小された例です)、ネストされたフラグメントを使用するのは理にかなっています。

完全なコードはここにあります。

4

0 に答える 0