Как показать диалоговое окно оповещения из не-пользовательского класса? получая ошибку типа -Не могу создать обработчик внутри потока, который не вызвал Looper.prepare () - PullRequest
2 голосов
/ 16 декабря 2011

получение ошибки, например -java.lang.RuntimeException: невозможно создать обработчик внутри потока, который не вызвал Looper.prepare ()

Я проверяю приложение, которое имеет много видов деятельности. Если пользователь не отвечает в течение определенного времени (15 минут), то через 15 минут я хочу показать диалоговое окно с вопросом: «Вы все еще там?» и если пользователь нажимает «НЕТ», приложение должно закрыться. Я пытался сделать это с помощью Приложение простое

но я не создал ControlApplication.java Я напрямую вызывал touch () из каждого моего действия. и вызвал конструктор класса Waiter из другого Java-файла, который является глобальным для моего приложения. вот мой код
Waiter.java

public class Waiter extends Thread
{
private static final String TAG=Waiter.class.getName();
private long lastUsed;
private long period;
private boolean stop;
private Context killContext;

public Waiter( long period, Context context )
{
    this.period=period;
    stop=false;
    killContext = context;
}

public void run()
{
    long idle=0;
    this.touch();
    do
    {
        idle=System.currentTimeMillis()-lastUsed;
        Log.d(TAG, "Application is idle for -------------------------------------->"+idle +" ms");
        Log.d(TAG, "lastUsed is  -------------------------------------->"+lastUsed +" ms");
        Log.d(TAG, "currentTimeMillis is  -------------------------------------->"+System.currentTimeMillis() +" ms");
        try
        {
            Thread.sleep(5000); //check every 50 seconds
        }
        catch (InterruptedException e)
        {
            Log.d(TAG, "----------------Waiter interrupted!-----------------------------------");
        }
        if(idle > period)
        {
            idle=0;
            Log.d(TAG, "----------------inside if-----------------------------------");
            AlertDialog.Builder killBuilder = new AlertDialog.Builder( killContext );                    
            killBuilder.setMessage("Are you still there ?")
                .setCancelable(false)
                .setPositiveButton("Yes",
                    new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int id)
                        {
                            dialog.cancel();
                        }
                    })
                    .setNegativeButton("No",
                        new DialogInterface.OnClickListener()
                    {
                        public void onClick(DialogInterface dialog, int id)
                        {
                            android.os.Process.killProcess(
                                android.os.Process.myPid() );
                        }
                    });
            Log.d(TAG, "----------------inside if killBuilder.create();;-----------------------------------");
            AlertDialog alert = killBuilder.create();
             Log.d(TAG, "----------------inside if alert.show();-----------------------------------");
            alert.show();
        }
    }
    while(!stop);
    Log.d(TAG, "--------------------------------Finishing Waiter thread-----------------------------");
}

public synchronized void touch()
{
    lastUsed=System.currentTimeMillis();
}

public synchronized void forceInterrupt()
{
    this.interrupt();
}

public synchronized void setPeriod(long period)
{
    this.period=period;
}

}

но в alert.show (); Я получаю выше ошибки. пожалуйста, помогите.

Ответы [ 5 ]

1 голос
/ 16 декабря 2011

AlertDialog не может быть показано ни в каком контексте, кроме текущей активности. Таким образом, вы должны быть уверены, что killContext расширяет класс Activity и теперь он записывается на экран.

1 голос
/ 16 декабря 2011

Проблема в том, что вы пытаетесь обновить пользовательский интерфейс из потока, не являющегося пользовательским интерфейсом, вы должны обновить пользовательский интерфейс из потока пользовательского интерфейса, только если вам нужно использовать Handler или runOnUiThread().

Попробуйте это,

killContext.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                alert.show();
            }
        });
0 голосов
/ 22 августа 2014

Я также заметил, что если процесс помещается в не-пользовательский поток и он вызывает предупреждение без runOnUiThread, это вызывает некоторое зависание, и Android-пользовательский поток идет в ANR ... У кого-нибудь есть такое же наблюдение?

0 голосов
/ 16 декабря 2011

Вы должны хранить Activity вместо Context в поле killContext, тогда вы можете позвонить runOnUiThread:

killActivity.runOnUiThread(new Runnable(){public void run(){alert.show();}})
0 голосов
/ 16 декабря 2011
  • лучший способ сделать это - AsyncTask.

  • Короткий путь - это вызов R unOnUiThread( new runnable) и запись диалогового окна, связанного с диалоговым окном оповещения.

  • альтернативный путь Handler реализация класса

...