Android:在一个单独的线程中输入对话框时Wait()主线程

我正在Android中编写一个用户修改SQL数据库的活动。 UI由用户输入名称的EditText和用户输入该人的吸引力的Seekbar组成。 下面有一堆按钮:添加,编辑,查看,删除。

当用户单击“编辑”按钮时,将显示一个输入对话框,要求用户输入记录编号。 完成后,将加载该记录。

我遇到的问题是inputdialog会显示,而当用户输入记录no时,编辑方法的其余部分将继续进行,以便当用户输入输入时 – 没有任何事情发生,因为该function已经已经完成。

为了解决这个问题,我决定使用multithreading(我没有太多使用经验)。 当按下编辑按钮时,主UI线程被阻止(使用wait() – 这是因为我不希望在用户输入记录ID时UI处于活动状态。)并且输入对话框显示在单独的线程。

输入输入后,将通知线程并继续编辑function的其余部分。 (代码如下)。

问题是,当我在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(); } } 

不不不! 不要阻止UI线程。 系统将引发“应用程序无响应”错误。 此外,不要尝试从非UI线程与用户交互。

当用户单击“编辑”时,不要启动编辑方法。 只需弹出一个对话框即可收集所需信息。 将DialogInterface.OnClickListener添加到肯定按钮,并(现在掌握所需信息)从那里开始编辑方法。

有关更多信息,请参阅指南主题对话框 。

在调用wait之前需要像这样得到对象锁:

  synchronized(Thread.currentThread()) { //added try { Thread.currentThread().wait(); } catch (InterruptedException e) { Log.e("Attractivometer","Main Thread interrupted while waiting"); e.printStackTrace(); } } 

但为什么你想让主线程等待?

首先,你不应该暂停主线程,因为如果你这样做,一切都将被冻结,从用户的角度来看,这根本就不好。

其次,你应该弹出一个带有2个按钮的对话框,(完成,取消),并允许用户按下其中一个按钮进一步。 在这里,您可以了解如何显示自定义对话框: http : //www.helloandroid.com/tutorials/how-display-custom-dialog-your-android-application

Android中multithreading编程的第一条规则是,您永远不应该停止UI线程,并且所有长时间运行的操作都应该在单独的线程中进行。 通过长时间运行我的意思是,SQLite数据库写/读等。