Не може да се създаде манипулатор в нишката, която не е извикала Looper.prepare() при изпълнение на мрежов процес

Опитвам се да стартирам мрежов процес във фонов режим на моето приложение, за да изпратя имейл. Тъй като това е мрежова задача, тя трябва да се изпълнява на отделна нишка във фонов режим. Не мога обаче да накарам нишката да се изпълни правилно. За да започна нова нишка, просто създавам такава и я стартирам с помощта на Thread.start(),

    new Thread(){


        public void run(){
                            Mail mail = new Mail();
            mail.setFrom("[email protected]");
            mail.setTo("[email protected]");
            mail.setSubject("Hello");
            mail.setMessage("World");

            try
            {
                if (mail.send())
                {
                    Toast.makeText(getActivity(),
                            "Email Sent Successfully", Toast.LENGTH_LONG)
                            .show();
                }

                else
                    Toast.makeText(getActivity(),
                            "Email Not Sent", Toast.LENGTH_LONG).show();

            }
            catch (Exception e)
            {
                Log.i("Debug","Could not send email - " + e);
                Log.i("Debug",e.getStackTrace().toString());
            }


        }
    }.start();

Въпреки това винаги получавам грешката Не мога да създам манипулатор в нишка, която не е извикала Looper.prepare()

Опитах няколко други неща, опитвайки се да предам Looper.getMainLooper() на нишката, чрез Handler с Runnable, но ми дава същата грешка. Също така се опитах да използвам AsyncTask, но изглежда, че тъй като това не е операция на потребителския интерфейс, използването на AsyncTask е неправилно (плюс това също ми дава същата грешка).

Ето моето проследяване на стека

 03-01 16:14:43.305: I/GreenBook(4454): java.lang.RuntimeException: Can't create handler inside     thread that has not called Looper.prepare()
03-01 16:14:43.305: I/GreenBook(4454):  at android.os.Handler.<init>(Handler.java:121)
03-01 16:14:43.305: I/GreenBook(4454):  at android.widget.Toast$TN.<init>(Toast.java:361)
03-01 16:14:43.305: I/GreenBook(4454):  at android.widget.Toast.<init>(Toast.java:97)
03-01 16:14:43.305: I/GreenBook(4454):  at android.widget.Toast.makeText(Toast.java:254)
03-01 16:14:43.305: I/GreenBook(4454):  at     com.stacksmashers.greenbook.RegisterActivity$10.run(RegisterActivity.java:688)

person sparkonhdfs    schedule 01.03.2014    source източник
comment
Моля, публикувайте проследяването на стека си.   -  person CommonsWare    schedule 02.03.2014
comment
Това е във въпроса ми сега.   -  person sparkonhdfs    schedule 02.03.2014
comment
Трябва да предоставите вашето пълно проследяване на стека.   -  person nKn    schedule 02.03.2014
comment
Това е пълното проследяване на стека. Само нишката улови изключение, така че не доведе до срив на цялото приложение, така че приложението продължи да работи дори след като нишката се срина.   -  person sparkonhdfs    schedule 02.03.2014
comment
Кой е ред 688 на вашия файл RegisterActivity.java?   -  person nKn    schedule 02.03.2014
comment
Това е редът if (mail.send()), защото чака методът за изпращане на поща да се върне след изпращане на пощата. (Знам, че класът/методите на пощата работят, защото съм ги тествал преди)   -  person sparkonhdfs    schedule 02.03.2014
comment
Е, там е виновникът. Това вероятно създава Handler и вашият Thread няма оператора Looper.prepare().   -  person nKn    schedule 02.03.2014


Отговори (1)


Не може да се създаде манипулатор в нишка, която не е извикала Looper.prepare()

Това е така, защото се опитвате да покажете Toast.

Също така се опитах да използвам AsyncTask, но изглежда, че тъй като това не е операция на потребителския интерфейс, използването на AsyncTask е неправилно

Toast ще се счита от повечето разработчици за част от потребителския интерфейс.

освен това ми дава същата грешка

Може би се опитвате да покажете Toast от doInBackground(). Покажете своя Toast в onPostExecute() (или onProgressUpdate(), ако изберете да се обадите на publishProgress()).

person CommonsWare    schedule 01.03.2014
comment
Благодаря! Това реши проблема! Не осъзнавах, че работя с UI в моя метод. Току-що извиках Toast в метода OnProgressUpdate, като част от задачата Async. - person sparkonhdfs; 02.03.2014
comment
проверете тази библиотека compile 'com.shamanland:xdroid-toaster:0.0.5', тя не изисква runOnUiThread() или Context променлива, цялата рутина е изчезнала! просто извикайте Toaster.toast(R.string.my_msg); ето примера: github.com/shamanland/xdroid-toaster-example - person Oleksii K.; 17.07.2014