安卓:wait()的主线程,而一个对话框,在一个单独的线程获取输入 [英] Android: Wait() the main thread while a dialog gets input in a separate Thread

查看:405
本文介绍了安卓:wait()的主线程,而一个对话框,在一个单独的线程获取输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写在那里的Andr​​oid用户修改SQL数据库的活动。用户界面包括用户在其中输入名称一个EditText,并在用户输入的人多么有吸引力是一个搜索栏的。底下有一堆按钮:添加,编辑,查看,删除。

在编辑按钮,用户点击时,会显示一个输入对话框,要求用户输入的记录数。一旦完成,该记录被加载。

我遇到的问题是,使用inputdialog将显示,并在用户输入记录中没有,所以,到时候用户做进入输入编辑方法的其余部分将进行 - 什么都没有发生,因为功能已经完成。

为了解决这个问题,我决定使用多线程(我没有用太多的经验)。当编辑按钮pressed,主UI线程被阻塞(使用的wait() - 这是因为我不希望当用户输入记录ID的UI活跃。)和输入对话框在一个单独的线程显示。

一旦输入已输入,该线程被通知和编辑功能的其余部分将继续。 (在code是下文)。

现在的问题是,当我呼吁UI线程等待功能,我得到,说:对象不是线程的wait()之前已锁定的错误。我如何锁定在UI线程?

我知道,一般人应该不会阻塞UI线程,但我认为这是在这种情况下,没关系,因为我不希望它接受任何用户输入。

感谢您的帮助。

 公共类Attractivometer扩展活动实现OnClickListener {    私人按钮buttonAddRecord,buttonEditRecord,buttonSaveChanges;
    私人按钮buttonDeleteRecord,buttonViewRecord;
    私人的EditText字段名;
    私人搜索栏seekbarAttractiveness;
    私人字符串inputFromInputDialog = NULL;
    私人螺纹inputThread;
    保护无效的onCreate(捆绑savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.Attractivometer);        buttonAddRecord =(按钮)findViewById(R.id.buttonAddRecord);
        buttonSaveChanges =(按钮)findViewById(R.id.buttonSaveChanges);
        buttonEditRecord =(按钮)findViewById(R.id.buttonEditRecord);
        buttonDeleteRecord =(按钮)findViewById(R.id.buttonDeleteRecord);
        buttonViewRecord =(按钮)findViewById(R.id.buttonViewRecord);        字段名=(的EditText)findViewById(R.id.fieldName);        seekbarAttractiveness =(搜索栏)findViewById(R.id.seekbarAttractiveness);        buttonAddRecord.setOnClickListener(本);
        buttonSaveChanges.setOnClickListener(本);
        buttonEditRecord.setOnClickListener(本);
        buttonDeleteRecord.setOnClickListener(本);
        buttonViewRecord.setOnClickListener(本);
    }
    公共无效的onClick(查看clickedItem)
    {        开关(clickedItem.getId())
        {
        案例R.id.buttonAddRecord:
            // .....
            打破;
        案例R.id.buttonSaveChanges:
          // ...
            打破;        案例R.id.buttonEditRecord:            inputThread =新主题(新的Runnable(){                公共无效的run()
                {
                    showInputDialog(输入记录ID,InputType.TYPE_CLASS_NUMBER);
                }            });
            inputThread.start();
            尝试{
                Thread.currentThread()等待()。
            }赶上(InterruptedException的E){
                Log.e(Attractivometer,主线程等待时被中断);
                e.printStackTrace();
            }            尝试{
                inputThread.join();
            }赶上(InterruptedException的E){
                Log.e(Attractivometer,输入螺纹而接合打断);
                e.printStackTrace();
            }            INT的recordId =的Integer.parseInt(inputFromInputDialog);
            如果(的recordId!= NULL)
            {
                AttractivometerSQLHandler AttractivometerDatabaseHandler =新AttractivometerSQLHandler(本);
                AttractivometerDatabaseHandler.openDatabase();
                字符串recordName = At​​tractivometerDatabaseHandler.getName(recordId所);
                字符串recordAttractiveness = At​​tractivometerDatabaseHandler.getAttractiveness(recordId所);                如果(recordName == NULL || recordAttractiveness == NULL)
                {
                    //没有找到记录。
                    Toast.makeText(这一点,不使用该ID记录发现,Toast.LENGTH_SHORT).show();
                }其他
                {
                    fieldName.setText(recordName);
                    seekbarAttractiveness.setProgress(的Integer.parseInt(recordAttractiveness));
                    recordIsOpen(真);
                }
                AttractivometerDatabaseHandler.closeDatabase();
            }其他
                //没有输入。
            recordIsOpen(假);            打破;        案例R.id.buttonDeleteRecord:
            // ...
            打破;        案例R.id.buttonViewRecord:
            // ....        }
    }    私人无效showInputDialog(字符串提示,诠释inputType下)
    {
        AlertDialog.Builder使用inputdialog =新AlertDialog.Builder(本);        inputDialog.setTitle(备案号);        最终的EditText fieldInput =新的EditText(本);
        fieldInput.setInputType(inputType下);
        fieldInput.setHint(提示);        inputDialog.setView(fieldInput);
        inputDialog.setPositiveButton(OK,新DialogInterface.OnClickListener()
        {            公共无效的onClick(DialogInterface为arg0,ARG1 INT)
            {
                inputFromInputDialog = fieldInput.getText()的toString()。
                inputThread.notify();            }
        });        inputDialog.setNegativeButton(取消,新DialogInterface.OnClickListener()
        {            公共无效的onClick(DialogInterface为arg0,ARG1 INT)
            {
                inputFromInputDialog = NULL;
                inputThread.notify();
            }
        });        inputDialog.show();
    }
}


解决方案

不,不,不!不要阻塞UI线程。该系统将引发一个应用程序没有响应的错误。另外,不要试图从一个非UI线程的用户进行交互。

当用户点击编辑,不启动编辑方法。只是弹出一个对话框来收集所需信息。添加 DialogInterface.OnClickListener 来的积极按钮(用现在手头所需的信息),从那里开始编辑方法。

查看引导话题对话框了解详情。

I'm writing an activity in Android where the user modifies an SQL Database. The UI consists of an EditText where the user enters the name, and a Seekbar where the user enters how attractive the person is. Underneath there are a bunch of buttons: add, edit, view, delete.

When the user clicks on the "Edit" button, an input dialog is displayed asking the user to input the record number. Once that is done, that record is loaded.

The problem I was having was that the inputdialog would be displayed and while the user entering the record no, the rest of the edit method would carry on so that by the time the user was done entering the input - nothing happened because the function had already been completed.

In order to solve this problem, I decided to use Multi-Threads (which I do not have much experience using). When the edit button is pressed, the main UI Thread is blocked (using wait() - this is because I don't want the UI to be active while the user is entering the record id.) and the input dialog is displayed in a seperate thread.

Once the input has been entered, the thread is notified and the rest of the edit function continues. (The code is below).

The problem is that when I call the wait function on the UI Thread, I get an error that says "object not locked by thread before wait() ". How do I lock the UI Thread?

I know in general one shouldn't block the UI Thread, but I think it's okay in this case because I don't want it to accept any user input.

Thanks for your help.

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

解决方案

No, no, no! Do not block the UI thread. The system will raise an "Application Not Responding" error. Also, do not try to interact with the user from a non-UI thread.

When the user clicks "edit", don't start the edit method. Just pop up a dialog to collect the required information. Add a DialogInterface.OnClickListener to the positive button and (with the required information now in hand) start the edit method from there.

See the guide topic Dialogs for more information.

这篇关于安卓:wait()的主线程,而一个对话框,在一个单独的线程获取输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆