方法getText必须从UI线程调用,当前推断的线程是worker

时间:2016-12-17 14:25:30

标签: java android email android-asynctask

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

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

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方法中的邮件对象。

2 个答案:

答案 0 :(得分:0)

你可以:

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

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

  • 将值传递到execute()方法并将其作为参数选取到doInBackground()

  • 实施onPreExecute()并从中检索值

答案 1 :(得分:0)

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