【问题标题】:Method getText must be called from the UI thread, currently inferred thread is worker方法getText必须从UI线程调用,目前推断线程为worker
【发布时间】:2023-03-25 20:33:01
【问题描述】:

我制作了一个使用 AsyncTask 执行的简单邮件应用程序。在 doInBackground 方法中,我启动了该类的 Mail 对象,该对象创建了一个邮件对象,该对象接受凭据、电子邮件主题、正文和附件等参数。无论如何,我想从几个 EditText 字段中获取 getText() 并将它们作为邮件正文传递,但问题是我不能在 doInBackground 方法中使用 getText() 方法,所以这会产生问题。

这是整个主要活动。我想不出一种在逻辑上以有效的方式绕过它的方法。

public class MainActivity extends Activity {

    public static File imageFile;
    public static EditText etM, etU, etO;
    public static Spinner elk;
    String[] elks = {"ED 1", "ED 2", "ED 3", "ED 4", "ED 5", "ED 6",
            "ED 7", "ED 8", "ED 9", "ED 10", "ED 11"};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_item, elks);

        spElk = (Spinner) findViewById(R.id.spElk);
        spElk.setAdapter(adapter);


        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

        StrictMode.setThreadPolicy(policy);

        final Button send = (Button) this.findViewById(R.id.bSubmit);
        send.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                new MainActivity.MailSender().execute();


            }
        });

        Button ibCam = (Button) findViewById(R.id.ibCam);
        ibCam.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                imageFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "temp.jpg");
                Uri tempUri = Uri.fromFile(imageFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
                startActivityForResult(intent, 0);
            }
        });

    }

    class MailSender extends AsyncTask<Void, Integer, Integer>
    {

        ProgressDialog pd = null;
        /* (non-Javadoc)
         * @see android.os.AsyncTask#onPreExecute()
         */

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            pd = new ProgressDialog(MainActivity.this);
            pd.setTitle("Uploading...");
            pd.setMessage("Uploading logs. Please wait...");
            pd.setCancelable(false);
            pd.show();
        }

        /* (non-Javadoc)
         * @see android.os.AsyncTask#doInBackground(Params[])
         */

        @Override
        protected Integer doInBackground(Void... params) {

            etM = (EditText)findViewById(R.id.etM);
            etU = (EditText)findViewById(R.id.etU);
            etO = (EditText)findViewById(R.id.etO);

            Mail m = new Mail("from_address@gmail.com", "pw123123");

            String toAddresses = "to_address@gmail.com";
            m.setToAddresses(toAddresses);
            m.setFromAddress("from_address@gmail.com");
            m.setMailSubject("Email subject");
            m.setMailBody(spElk.getSelectedItem().toString() + etM.getText().toString(), etU.getText().toString());



            try {
                m.addAttachment(imageFile.getAbsolutePath());

                if (m.send()) {
                    System.out.println("Message sent");
                    return 1;
                } else {
                    return 2;
                }

            } catch (Exception e) {
                Log.e("MailApp", "Could not send email", e);
            }
            return 3;
        }

        /* (non-Javadoc)
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */

        @Override
        protected void onPostExecute(Integer result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            pd.dismiss();

            if(result==1)
                Toast.makeText(MainActivity.this, "Sent.", Toast.LENGTH_LONG).show();
            else if(result==2)
                Toast.makeText(MainActivity.this, "Not sent.", Toast.LENGTH_LONG).show();
            else if(result==3)
                Toast.makeText(MainActivity.this, "Error sending message.", Toast.LENGTH_LONG).show();
        }
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if(requestCode == 0){

            switch(resultCode){

                case Activity.RESULT_OK:
                    if(imageFile.exists()){
                        Toast.makeText(this, "Image saved at: " + imageFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
                    }
                    break;

                case Activity.RESULT_CANCELED:
                    Toast.makeText(this, "Error submitting image", Toast.LENGTH_LONG).show();
                    break;

                default:
                    break;
            }

        }

    }
}

忽略任何字段命名不匹配。我只需要一种方法来获取这些值并在 doInBackground 方法中将它们传递给我的邮件对象。

【问题讨论】:

  • onPreExecute 中使用findViewById 而不是doInBackground

标签: java android email android-asynctask


【解决方案1】:

你可以:

  • 将值传递到您添加到类中的MailSender 构造函数,或者

  • 在开始任务之前调用您添加到 MailSender 的 setter 方法,或者

  • 将值传递给execute() 方法并将它们作为参数传递给doInBackground(),或者

  • 实现onPreExecute() 并从那里检索值

【讨论】:

  • 底线是我在 doInBackground 方法内创建 Mail 对象,那么我应该如何在 onPreExecute within doInBackground 方法内检索值?
  • @MilesWeirdo:将字段添加到MailSender。使用构造函数(第一个项目符号)、setter(第二个项目符号)或onPreExecute()(第四个项目符号)填充这些字段。阅读doInBackground() 中的字段。只要确保如果您使用 setter 方法,在调用 execute() 开始任务之前调用这些 setter。
【解决方案2】:

@CommonsWare 提出了四种访问值的方法。如下实现第四个

class MailSender extends AsyncTask<String, Integer, Integer>
    {

        ProgressDialog pd = null;
        /* (non-Javadoc)
         * @see android.os.AsyncTask#onPreExecute()
         */

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
        //rest of your code
        }

        /* (non-Javadoc)
         * @see android.os.AsyncTask#doInBackground(Params[])
         */

        @Override
        protected Integer doInBackground(String... params) {
        //rest of code
        //you can get values params[0],params[1] simillarly
            return yourIntValue;
        }

        /* (non-Javadoc)
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */

        @Override
        protected void onPostExecute(Integer result) {
            //rest of your code
        }
    }

并在 onCreate 方法中获取视图

 etM = (EditText)findViewById(R.id.etM);
            etU = (EditText)findViewById(R.id.etU);
            etO = (EditText)findViewById(R.id.etO);

现在调用 asyncTask 为:

new MainActivity.MailSender().execute(spElk.getSelectedItem().toString() + etM.getText().toString(), etU.getText().toString());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    相关资源
    最近更新 更多