Я показываю свое диалоговое окно предупреждения в отдельном потоке, и оно не работает для меня. сначала, когда я нажимаю
кнопку регистрации на 3000 мс. Я показываю диалог о ходе. и после этого я хочу показать окно предупреждения, но оно не работает. Как это решить?
Заранее спасибо...!
register.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.v(TAG, "Trying to Login");
showDialog(0);
t = new Thread() {
public void run() {
showDialog(0);
try {
Thread.sleep(3000);
removeDialog(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t.start();
try {
some data sending to server
Object responce=(Object)soapEnvelope.getResponse();
temp=responce.toString();
if(temp.equals("1")){
temp = "The result is 1";
}
System.out.println("The result is "+temp);
new Thread()
{
public void run()
{
try
{
sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
AlertDialog.Builder successfullyLogin = new Builder(Register.this);
successfullyLogin.setCancelable(false);
successfullyLogin.setMessage("Successfully Login !").show();
//Toast.makeText(getBaseContext(), "Toast text", Toast.LENGTH_LONG).show();
}
};
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case 0: {
dialog = new ProgressDialog(this);
dialog.setMessage("Please wait while connecting...");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
}
return dialog;
}
return null;
}
Замените все свои потоки на классы AsyncTask. Они разработаны специально для этого типа вещей и отлично работают с пользовательским интерфейсом для отображения диалогов и отбрасывают их в потоке пользовательского интерфейса, в то же время работая в фоновом режиме там, где вам это нужно.
Таким образом, вам не нужен тайм-аут в 3000 мс, он просто увольняется, когда он возвращается. Конечно, вы могли бы время, сколько времени займет вход в систему, и сохранить диалог до тех пор, пока вы не достигнете 3000 мс, но я бы этого не сделал. Кроме того, если вы хотите приостановить работу в Android, используйте SystemClock.sleep(3000);
вместо сотового потока Java, поскольку вам не нужно пытаться/улавливать прерывание.
Пример, который заменяет ваш код (обратите внимание на полное отсутствие потоков, try/catch и т.д., Которые обычно мутируют код потока):
// ... initialising onClickListener of your button to call the async task
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new StartLoginAsyncTask(YOURAPP.this).execute((Void []) null);
}
});
}
private class StartLoginAsyncTask extends AsyncTask<Void, Void, Integer> {
private ProgressDialog dialog;
private final Context context;
public StartLoginAsyncTask(Context context) {
this.context = context;
}
@Override
protected void onPreExecute() {
// UI work allowed here
dialog = new ProgressDialog(context);
// setup your dialog here
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(context.getString(R.string.please_wait_message));
dialog.setCancelable(false);
dialog.show();
}
@Override
protected Integer doInBackground(Void... ignored) {
Integer returnCode = doLogin();
return returnCode;
}
@Override
protected void onPostExecute(Integer returnCode) {
// UI work allowed here
dialog.dismiss();
if (returnCode == LOGIN_OK) {
// ... show other dialogs here that it was OK
} else {
// ... bad news dialog here
}
}
}
private Integer doLogin() {
// ... write your login code here.
// This is run in background, do not do any UI work here
return LOGIN_OK;
}
Если вы хотите, чтобы логин прерывал диалог, добавьте пользовательское TimeoutException
в doLogin()
, поймайте его в doInBackground()
и верните соответствующий ответ Integer и обработайте его в onPostExecute()
.
Взгляните на AsyncTask
Из JavaDocs: AsyncTask позволяет правильно и легко использовать поток пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и/или обработчиками.
Внутри потока вы должны использовать Handler для отображения AlertDialog:
Handler messageHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 111:
// Build and show AlertDialog here
break;
}
}
}
Используйте ниже вместо showdialog (0);
messageHandler.sendEmptyMessage(111);
Я думаю, что диалог может отображаться только из основного потока пользовательского интерфейса. Таким образом, идея заключалась бы в том, чтобы иметь обработчик в вашем основном потоке и публиковать сообщение на нем из нового потока, который запустит диалог.
AsyncTask<Void, Void, String>
, а затем изменяете типы возвращаемого значения / параметра в соответствии с необходимостью вdoInBackground()
иonPostExecute()
.