ユーザに新しいフローオブジェクトを作成させ、それをArrayListに追加してツールバーの"+"
を押したときの経過を追跡しようとしています。Android:新しいオブジェクトを作成し、同期メソッドを使用して新しいメソッドを操作/呼び出しする
オブジェクトがインスタンス化される前に、オブジェクトとそのプロパティを必要とする私の方法は、実行されているので、私は、Javaをマルチスレッドに苦しんでいますが問題
のすべての種類は、私は私の方法は、連続的に(つまり実行したい原因。ダイアログの表示、名前の取得、オブジェクトコンストラクタの使用、リストへの新しいオブジェクトの追加)。これは、私が宣言したがインスタンス化しなかったオブジェクトに対してSynchronized
アクションを使用しようとした理由です。
ロックされたオブジェクトはnullにできないため、この方法は機能していないようです。
private Flow newFlow; //Blank flow object declared.
private static List<Flow> flowsInStream = new ArrayList<Flow>();
synchronized (newFlow) {
flowDialog();
// presents user a dialog box to receive input.
// takes user input, invokes separate method to actually instantiate
// the newFlow object using the user input.
// Originally blank newFlow object now has:
// newFlow.name = userInput
// --X END X--
addToStream(newFlow);
// adds the newly instantiated newFlow object to the flowsInStream
// array to keep track of them.
// --X END X--
executedCorrectly();
// displays log message showing both the newFlow.name & the current
// elements in the flowsInStream array.
// --X END X--
} // end of synchronized
TheStream.java
public class TheStream extends AppCompatActivity {
private static final String TAG = TheStream.class.getName();
private Toolbar streamToolbar;
private Flow theFlow; //Blank flow object declared.
private static List<Flow> flowsInStream = new ArrayList<Flow>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_the_stream);
streamToolbar = (Toolbar) findViewById(R.id.streamToolbar);
setSupportActionBar(streamToolbar);
}
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu_thestream, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
// User chose the "Settings" item, show the app settings UI...
return true;
case R.id.action_newFlow:
flowDialog();
addToStream(theFlow);
executedCorrectly();
return true;
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
public void flowDialog() {
//Creates dialog box asking for name for the new flow
AlertDialog.Builder newFlowDialog = new AlertDialog.Builder(TheStream.this);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
params.setMarginStart(70);
params.setMarginEnd(150);
//Create edit text field for name entry
final EditText nameInputET = new EditText(TheStream.this);
//Sets maximum length of the EditText
nameInputET.setFilters(new InputFilter[]{new InputFilter.LengthFilter(30)});
//Adds the ET and params to the layout of the dialog box
layout.addView(nameInputET, params);
newFlowDialog.setTitle("Name your new Flow.");
newFlowDialog.setIcon(R.drawable.new_flow);
newFlowDialog.setView(layout);
newFlowDialog.setPositiveButton("Lets Roll",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if (nameInputET.getText().toString().equals("")) {
Toast.makeText(TheStream.this, "Every Flow deserves a good name :(", Toast.LENGTH_LONG).show();
flowDialog(); //Recall the dialog
} else {
// Sets name of flow object
theFlow = instantiateFlow(nameInputET.getText().toString());
}
}
});
newFlowDialog.setNegativeButton("Nevermind",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
//Display Alert
newFlowDialog.show();
}
protected Flow instantiateFlow(String userInput) {
//Instantiates (Constructor) the newFlow object.
Flow newFlow = new Flow(userInput);
Log.d(TAG, "Your flow's name is " + newFlow.getFlowName());
/** Returns errors attached below */
return newFlow;
}
public void addToStream(Flow flow) {
flowsInStream.add(flow);
}
public void executedCorrectly() {
Log.d(TAG, "The synchronized activity executed correctly because the new Flow object's name is " + theFlow.getFlowName());
Log.d(TAG, "The new Flow list is also updated check it out: " + flowsInStream);
}
}
Flow.java
public class Flow {
private String flowName;
public Flow() {
} // End of default constructor
public Flow(String flowName) {
this.flowName = flowName;
} // End of constructor
/** Getters & Setters **/
public void setFlowName(String flowName) {
this.flowName = flowName;
}
public String getFlowName() {
return this.flowName;
}
:
java.lang.NullPointerException: Null reference used for synchronization (monitor-enter)
私は私の方法を作ることができる方法上の任意の考えでは、この擬似コードのようなシリアルで実行されます
追加コードがあれば私は助けて、私に知らせて、私はいくつかを投稿することを嬉しく思います。可能であれば、私の技術的な理解が欠けていた箇所を答えてください。受領
ERROR:newFlow
はまだnull
とき
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String nhacks16.flow.Main.Flow.getFlowName()' on a null object
reference
こんにちはmastov、返信いただきありがとうございます。同期を使用しない場合、メソッドをシリアルで実行するにはどうすればよいですか?実行する前に、最初のメソッド(flowDialog)が完了するまで、2つ目のメソッド(addToStream)を待つようにします。 – Rob
@RobertSimoes:マルチスレッドを使用しない場合、何もする必要なしに「シリアルに」実行されます。あなたはマルチスレッドが進行中であると思いますか? – mastov
元々は、同期化されたブロックを使わずにメソッドを次々に入れただけで、ログメッセージを受け取ることになりました。 "新しいFlowオブジェクトの名前が** null **であるため同期化されたアクティビティが正しく実行されました" オブジェクトがflowDialog()でインスタンス化される前に、LogメッセージがnewFlow.nameを取得したことを示します。 – Rob