0

添付ファイル付きのさまざまなメールを送信するクラスがあります。

この方法sendEmail(addresses);では添付ファイルをアップロードしてメールを送信するのに時間がかかるため、待機中のダイアログを表示するAsyncTaskを作成しました。

ただし、残念ながら、送信中、アプリは何も表示せずに送信を終了するまでフリーズします(または、手順が終了する前に少しの間フリーズした待機ウィンドウが表示される場合があります)

私のクラスのコードの関連部分は次のとおりです

public class MyClass extends Activity {
    ...

    private ProgressDialog waitingDialog;

    ....

    OnClickListener mInvia = new OnClickListener() {
        public void onClick(View v) {
                new MyAsyncTaskClass().execute(new String[] {});
        }
    };

    public void prepareSending() {
        String x = "";
        for (String s : selectedMails) {
            x += (s + ";");
        }
        String[] addresses = x.split(";");
        sendEmail(addresses);
    }

    private void openFile() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.setType("file/*");
        startActivityForResult(i, FILE_REQ_CODE);
    }

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

        Uri tmp = intentData.getData();
        filePath=getRealPath(tmp);
        super.onActivityResult(requestCode, resultCode, intentData);

    }


    public void sendEmail(String[] addresses) {

        Mail m = new Mail("sendermail@sample.com",
                "senderpassword");

        name = editor1.getText().toString();
        subject = editor2.getText().toString();
        text = editor3.getText().toString();
        emailReply = editor4.getText().toString();

        m.setTo(addresses);
        m.setFrom(emailReply);
        m.setSubject(subject);
        m.setBody(text + "\n\n\n Sent by" + name);
        try {
            m.send();
        } catch (Exception e) {
            Log.e("MyClass", "Cannot send email", e);
        }

        try {
            m.addAttachment(filePath);

            if (m.send()) {
                Alerts.Ok(MyClass.this);
                nSuccess++;
            } else {
                Alerts.ErrorSending(MyClass.this);
            }
        } catch (Exception e) {
            Alerts.ErrorAttachment(MyClass.this);
        }

    }

    //inner class that should show a waiting windows
    private class MyAsyncTaskClass extends AsyncTask<String, Void, Void> {

        @Override
        protected void onPreExecute() {
            waitingDialog = new ProgressDialog(MyClass.this);
            waitingDialog.setMessage("Loading ....");
            waitingDialog.setIndeterminate(true);
            waitingDialog.setCancelable(true);
            waitingDialog.show();
        }

        @Override
        protected Void doInBackground(final String... strings) {
            try {
                runOnUiThread(new Runnable() {
                    public void run() {
                        prepareSending();
                    }

                });
            } catch (Exception e) {

            }
            return null;
        }

        @Override
        protected void onPostExecute(Void params) {
            waitingDialog.dismiss();
        }
    }

    //end innerclass
    // start context menu code
    ......

}
4

4 に答える 4

2

問題

UIスレッドですべてを実行しているためだと思います。

    @Override
    protected Void doInBackground(final String... strings) {
        try {
            runOnUiThread(new Runnable() {
                public void run() {
                    prepareSending();
                }

            });
        } catch (Exception e) {

        }
        return null;
    }

代わりにこれを行ってください!

doInBackgroundUIに依存しないものに基づいてすべてのコードを実行します。

    @Override
    protected Void doInBackground(final String... strings) {
        prepareSending();
        return null;
    }

UIへのアクセス

UIまたはUIスレッド上の他のデータにアクセスする必要がある場合は、最初にそれを実行します。

    protected void onPreExecute() {
        // Find all your "editor" fields here, and save them to member variables within the AsyncTask.
        // ...
    }

次に、それらをメソッドに送信します

そのデータprepareSendingsendEmailパラメータとして受け入れます。

public void prepareSending(String name, String subject, String text, String emailReply) {
    // ...
    sendEmail(addresses, name, subject, text, emailReply);
}
public void sendEmail(String[] addresses, String name, String subject, String text, String emailReply) {
    // ...
}

そして最後に、あなたはそれらをから送る必要がありますdoInBackground

    @Override
    protected Void doInBackground(final String... strings) {
        prepareSending(mName, mSubject, mText, mEmailReply); // The local fields you saved earlier
        return null;
    }
于 2012-10-03T20:31:54.267 に答える
0
private class MyAsyncTaskClass extends AsyncTask<String, Integer, Integer> {
        ProgressDialog waitingDialog;

        @Override
        protected void onPreExecute() {
            waitingDialog = new ProgressDialog(MyClass.this);
            waitingDialog.setMessage("Loading ....");
            waitingDialog.setIndeterminate(true);
            waitingDialog.setCancelable(true);
        }

        @Override
        protected Integer doInBackground(final String... strings) {
            setProgress(-1);
            // long process start
            prepareSending();
            // long process end
            setProgress(-2);
            return 0;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {

            if (values[0] == -1) {
                waitingDialog.show();
            } else if (values[2] == -2) {
                waitingDialog.dismiss();
            }
        }

        @Override
        protected Integer onPostExecute(Integer params) {
        }
    }
于 2012-10-03T20:59:16.553 に答える
0

これは推奨される方法ではありません。

    @Override
    protected Void doInBackground(final String... strings) {
        try {
            runOnUiThread(new Runnable() {
                public void run() {
                    prepareSending();
                }

            });
        } catch (Exception e) {

        }
        return null;
    }

処理の進行中にUIスレッドで何かを実行するには、publishProgress()を使用する必要があります。

とは言うものの、あなたは活動が破壊される可能性のあるケースも管理していません。これにより、メモリリークが発生し、複数のAsyncTaskがバックグラウンドで実行される可能性があります。

次のようなものに到達してみてください:

public static class MyAsyncTask extends AsyncTask<Void, Void, Void> {

  MyAsyncTask(MyActivity a) {
    activity = new WeakReference<MyActivity>(a);
  }

  @Override
  protected void onPreExecute() {
    if (activity.get()!=null) activity.get().showDialog();
  }

  @Override
  protected Void doInBackground(Void... params) {
    // Upload data from here
  }
  @Override
  protected void onPostExecute(Void params) {    
    if (activity.get()!=null) activity.get().dismissDialog();
  }


  private WeakReference<MyActivity> activity;
}

タスクを非インスタンス状態として保存し、必要に応じてダイアログを閉じて再作成することで、アクティビティに応答できます...

最後に、メールをタスクコンストラクターに送信するために必要なすべての情報(コンテンツ、件名、...)を渡します。タスクを作成すると、すべてのUIアクセスがUIスレッドで実行されます(現在のようにdoInBackgroundでは実行されません)。

于 2012-10-03T20:32:04.673 に答える
0

問題はここにあります:

try {
        runOnUiThread(new Runnable() {
                public void run() {
                    prepareSending();
                }

            });
    } catch (Exception e) {

    }

1) prepareSending(); メソッドが UI スレッドで呼び出されます。AndroidでAsyncTaskを使用する方法を理解するには、これを参照してください。

2)また、一般的な例外をキャッチして処理しないという習慣があるようです。コード スタイル ガイドラインを参照してください。それはあなたを大いに助けます。

幸運を ;)

于 2012-10-03T20:40:51.990 に答える