我正在编写一个Android活动,用户可以修改SQL数据库。该UI包括一个EditText和一个SeekBar,用户可以在其中输入名称和人物的吸引力值。下面有一系列按钮:添加、编辑、查看、删除。
当用户点击“编辑”按钮时,会显示一个输入对话框,要求用户输入记录号。完成后,该记录将被加载。
我遇到的问题是,在用户输入记录编号时,输入对话框会显示出来,而余下的编辑方法仍然在运行,因此当用户完成输入时,已经没有任何操作发生了,因为函数已经完成了。
为解决这个问题,我决定使用多线程(我没有使用多线程的经验)。当按下编辑按钮时,主UI线程被阻塞(使用wait(),这是因为我不希望用户输入记录ID时UI处于活动状态),并在单独的线程中显示输入对话框。
一旦输入完成,线程就会被通知,并且编辑功能的其余部分将继续进行。(代码如下)。 问题在于当我在UI线程上调用wait函数时,我会得到一个错误,说“wait()之前对象未被线程锁定”。我该如何锁定UI线程? 我知道通常不应该阻塞UI线程,但我认为在这种情况下这样做是可以接受的,因为我不希望它接受任何用户输入。
感谢您的帮助。
当用户点击“编辑”按钮时,会显示一个输入对话框,要求用户输入记录号。完成后,该记录将被加载。
我遇到的问题是,在用户输入记录编号时,输入对话框会显示出来,而余下的编辑方法仍然在运行,因此当用户完成输入时,已经没有任何操作发生了,因为函数已经完成了。
为解决这个问题,我决定使用多线程(我没有使用多线程的经验)。当按下编辑按钮时,主UI线程被阻塞(使用wait(),这是因为我不希望用户输入记录ID时UI处于活动状态),并在单独的线程中显示输入对话框。
一旦输入完成,线程就会被通知,并且编辑功能的其余部分将继续进行。(代码如下)。 问题在于当我在UI线程上调用wait函数时,我会得到一个错误,说“wait()之前对象未被线程锁定”。我该如何锁定UI线程? 我知道通常不应该阻塞UI线程,但我认为在这种情况下这样做是可以接受的,因为我不希望它接受任何用户输入。
感谢您的帮助。
public class Attractivometer extends Activity implements OnClickListener {
private Button buttonAddRecord, buttonEditRecord, buttonSaveChanges;
private Button buttonDeleteRecord, buttonViewRecord;
private EditText fieldName;
private SeekBar seekbarAttractiveness;
private String inputFromInputDialog=null;
private Thread inputThread;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.Attractivometer);
buttonAddRecord = (Button) findViewById(R.id.buttonAddRecord);
buttonSaveChanges = (Button) findViewById(R.id.buttonSaveChanges);
buttonEditRecord = (Button) findViewById(R.id.buttonEditRecord);
buttonDeleteRecord = (Button) findViewById(R.id.buttonDeleteRecord);
buttonViewRecord = (Button) findViewById(R.id.buttonViewRecord);
fieldName = (EditText) findViewById(R.id.fieldName);
seekbarAttractiveness = (SeekBar) findViewById(R.id.seekbarAttractiveness);
buttonAddRecord.setOnClickListener(this);
buttonSaveChanges.setOnClickListener(this);
buttonEditRecord.setOnClickListener(this);
buttonDeleteRecord.setOnClickListener(this);
buttonViewRecord.setOnClickListener(this);
}
public void onClick(View clickedItem)
{
switch(clickedItem.getId())
{
case R.id.buttonAddRecord:
//.....
break;
case R.id.buttonSaveChanges:
//...
break;
case R.id.buttonEditRecord:
inputThread = new Thread(new Runnable(){
public void run()
{
showInputDialog("Enter Record ID", InputType.TYPE_CLASS_NUMBER);
}
});
inputThread.start();
try {
Thread.currentThread().wait();
} catch (InterruptedException e) {
Log.e("Attractivometer","Main Thread interrupted while waiting");
e.printStackTrace();
}
try {
inputThread.join();
} catch (InterruptedException e) {
Log.e("Attractivometer","Input Thread interrupted while joining");
e.printStackTrace();
}
int recordId = Integer.parseInt(inputFromInputDialog);
if(recordId!=null)
{
AttractivometerSQLHandler AttractivometerDatabaseHandler = new AttractivometerSQLHandler(this);
AttractivometerDatabaseHandler.openDatabase();
String recordName = AttractivometerDatabaseHandler.getName(recordId);
String recordAttractiveness = AttractivometerDatabaseHandler.getAttractiveness(recordId);
if(recordName==null || recordAttractiveness==null )
{
//no record found.
Toast.makeText(this, "No record with that ID found", Toast.LENGTH_SHORT).show();
}else
{
fieldName.setText(recordName);
seekbarAttractiveness.setProgress( Integer.parseInt(recordAttractiveness) );
recordIsOpen(true);
}
AttractivometerDatabaseHandler.closeDatabase();
}else
//No input.
recordIsOpen(false);
break;
case R.id.buttonDeleteRecord:
//...
break;
case R.id.buttonViewRecord:
//....
}
}
private void showInputDialog(String prompt, int inputType)
{
AlertDialog.Builder inputDialog = new AlertDialog.Builder(this);
inputDialog.setTitle("Record No.");
final EditText fieldInput = new EditText(this);
fieldInput.setInputType(inputType);
fieldInput.setHint(prompt);
inputDialog.setView(fieldInput);
inputDialog.setPositiveButton("OK", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface arg0, int arg1)
{
inputFromInputDialog = fieldInput.getText().toString();
inputThread.notify();
}
});
inputDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface arg0, int arg1)
{
inputFromInputDialog = null;
inputThread.notify();
}
});
inputDialog.show();
}
}