ここに簡単なプログラムがあります。「+」を押すと、リストに新しい番号が追加されます。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
フラグメントに追加されています。これは、実際のプログラムがより複雑であるため(これは縮小された例です)、ネストされたフラグメントを使用するのは理にかなっています。
完全なコードはここにあります。