I want to handle unhandled exception in my app without any third-party libraries.
So i write a code.
Activity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Thread.setDefaultUncaughtExceptionHandler(new ReportHelper(this));
throw new NullPointerException();
}
My crash handler :
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.widget.Toast;
/**
* Created by S-Shustikov on 08.06.14.
*/
public class ReportHelper implements Thread.UncaughtExceptionHandler {
private final AlertDialog dialog;
private Context context;
public ReportHelper(Context context) {
this.context = context;
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Application was stopped...")
.setPositiveButton("Report to developer about this problem.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Not worked!
dialog.dismiss();
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
}
});
dialog = builder.create();
}
#Override
public void uncaughtException(Thread thread, Throwable ex) {
showToastInThread("OOPS!");
}
public void showToastInThread(final String str){
new Thread() {
#Override
public void run() {
Looper.prepare();
Toast.makeText(context, "OOPS! Application crashed", Toast.LENGTH_SHORT).show();
if(!dialog.isShowing())
dialog.show();
Looper.loop();
}
}.start();
}
}
When i start app as you see i throwed NullPointerException. Toast in my handling logic was showed, and dialog was showed too. BUT! Dialog clicks was not handling correct. I mean logic in onClick method was not worked. What the problem and how i can fix that?
In my case, I moved AlertDialog.Builder in thread run function like this:
public void showToastInThread(final String str){
new Thread() {
#Override
public void run() {
Looper.prepare();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Application was stopped...")
.setPositiveButton("Report to developer about this problem.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Not worked!
dialog.dismiss();
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
}
});
dialog = builder.create();
Toast.makeText(context, "OOPS! Application crashed", Toast.LENGTH_SHORT).show();
if(!dialog.isShowing())
dialog.show();
Looper.loop();
}
}.start();
}
and all thing work perfectly.
Hope this help you.
According this post, the state of the application is unknown, when setDefaultUncaughtExceptionHandler is called. This means that your onClick listeners may not be active anymore.
Why not use this method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.main);
Thread.setDefaultUncaughtExceptionHandler(new ReportHelper(this));
throw new NullPointerException();
} catch (NullPointerException e) {
new ReportHelper(this);
}
}
and remove ReportHelper implementing the Thread.UncaughtExceptionHandler interface.
Your method of not explicitly catching exceptions can be seen as an anti-pattern.
Since an exception occurs on the UI-Thread: the state of this thread is probably unexpected
So try simply this in your click handler :
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
android.os.Process.killProcess(android.os.Process.myPid());
}
});
Related
I want to show AlertDialog which is in other class in AsyncTask.
Example>
public class WardListAsyncTask extends AsyncTask<HashMap<String, String>, String, Object> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Object doInBackground(HashMap<String, String>... params) {
...
}
#Override
protected void onPostExecute(Object result) {
ConfirmAlertDialog(ez_WardList.this,"HI?");
//this method is in another Class & I want to use this method another Asynctask also..
}
and ConfirmAlertDialog is...
Context g_ctx;
String g_content;
public void ez_ConfirmAlertDialog(Context ctx, String content) {
this.g_ctx=ctx;
this.g_content=content;
runOnUiThread(new Runnable() {
#Override
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(g_ctx, AlertDialog.THEME_HOLO_LIGHT);
builder.setMessage(g_content).setPositiveButton(getString(R.string.kor_confirm),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
alertDialog.getWindow().setLayout(displayWidth / 2, LayoutParams.WRAP_CONTENT);
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.rgb(10, 174, 239));
}
});
}
I think g_ctx.class.runonuiThread ... but I can't call runonuithread...
How can I solve it?
runOnUiThread method is present in Activity class. So should pass Activity into your class.
Example:
public class MyClass{
public void ez_ConfirmAlertDialog(Activity activity, String content) {
this.g_ctx=ctx;
this.g_content=content;
if(activity == null){
return;
}
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(g_ctx, AlertDialog.THEME_HOLO_LIGHT);
builder.setMessage(g_content).setPositiveButton(getString(R.string.kor_confirm),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
alertDialog.getWindow().setLayout(displayWidth / 2, LayoutParams.WRAP_CONTENT);
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.rgb(10, 174, 239));
}
});
}
}
You can call it in main thread using handler
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// Your code here
}
});
I wanna create android app which after 30 second will display to me AlertDialog
I did it but i wanna make AlertDialog will display any where in android for example in home of android.
like this http://www.papktop.com/wp-content/uploads/2012/01/Popup-Notifier-1.jpg
it is my code (main Activity )
public class MainActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//EventBus.getDefault().register(this);
mTextField = (TextView) findViewById(R.id.mTextField);
}
public void show(View view) {
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setMessage("Nek Test");
// alertDialog.setIcon(getResources().getDrawable(R.mipmap.notification_image));
alertDialog.setTitle("Reminder");
alertDialog.setPositiveButton("Got it", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
alertDialog.show();
}
}.start();
}
}
For show a dialog outside the app, for example over the Home you need to put this permission in the manifest:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Create a service like this:
public class AlertService extends Service {
private static Context context;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setMessage("Nek Test");
alertDialog.setTitle("Reminder");
/**ADD THIS FOR DISPLAY THE ALERT ANYWHERE*/
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.setPositiveButton("Got it", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
alertDialog.show();
}
}.start();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}//End class
And finally start the service from activity:
startService(new Intent(this, AlertService.class));
and add this line into the "application" tag in the manifest:
<service android:name=".AlertService" />
There are many ways to do this :
1- Implement a service that will start in the main activity and in the service execute a timer, and whenever the timer finishes it will call a broadcast receiver and this receiver will trigger the showing of the alert dialogue.
2- You could use otto : http://square.github.io/otto/
In otto you have to register every activity to otto and unregister onDestroy off course. The timer has to be in an asynctask and on the post execute you post a certain result. Then you subscribe the onAsyncTaskResult in each activity and trigger the alert dialogue there.
3- You also use otto but this time do not subscrib to onAsyncTaskResult and instead of posting in the onPostExecute send a broadcast. Have a broadcast listener ready and on receive show the alert dialogue
This code works best for me without any errors
public class AlertService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final AlertDialog alertDialog = new AlertDialog.Builder(AlertService.this).create();
alertDialog.setMessage("Nek Test");
alertDialog.setTitle("Reminder");
alertDialog.setButton("Got it", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
/**ADD THIS FOR DISPLAY THE ALERT ANYWHERE*/
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
return flags;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
I am trying to open a AlertDialog. When this AlertDialog is opened, the threads need to wait for user input in order to continue its program. I read that I need to lock the object thats need to wait and notified. When I run this code on my phone. The alertdialog won't show, and it looks like the app is looping, because after a few seconds I get a message that the app isn't responding. Below you will find the code I wrote.. By the way. I am a virgin to android programming. So please be gentle :P
public class EditTagActivity extends Activity{
AlertDialog alertDialog;
Runnable h = new Runnable()
{
# Override
public void run()
{
alertDialog.show();
synchronized(g)
{
try
{
Log.d("Threads", "g.wait()");
g.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
};
Runnable g = new Runnable()
{
#Override
public void run()
{
Log.d("Threads", "createAlertDialog()");
createAlertDialog();
runOnUiThread(h);
}
};
public AlertDialog alert;
Runnable test = new dialogManager();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_tag);
Log.d("Threads", "setup()");
setup();
}
void setup()
{
Log.d("Threads", "g.run()");
g.run();
}
void createAlertDialog()
{
Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Alert");
alert.setMessage("Flaq");
alert.setPositiveButton("OK", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
synchronized(g)
{
Log.d("Threads", "g.notifyAll");
g.notifyAll();
}
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
synchronized(g)
{
Log.d("Threads", "g.notifyAll");
g.notifyAll();
}
}
});
alertDialog = alert.create();
}
}
Instead of Java's Thread and Runnable approach, you should use Android's AsyncTask, It helps you resolve this more simply by overriding the onPreExecute and onPostExecute methods to handle things just before and after running the code in background.
This post has a good example for using the AsyncTask class.
I am building a chat application in Android with backend MySQL, PHP nand running on local network with Apache. However, as a uses attempts to sign up, the LogCat displays a Nullpoint error on line 112, at "public void run()".
I have reviewed the code multiple times but cannot locate why a null point error persists...any siuggestions?
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.baidar.androidChatter.interfacer.Manager;
import com.baidar.androidChatter.serve.MessagingService;
public class SigningUp extends Activity {
private static final int FILL_ALL_FIELDS = 0;
protected static final int TYPE_SAME_PASSWORD_IN_PASSWORD_FIELDS = 1;
private static final int SIGN_UP_FAILED = 9;
private static final int SIGN_UP_USERNAME_CRASHED = 3;
private static final int SIGN_UP_SUCCESSFULL = 4;
protected static final int USERNAME_AND_PASSWORD_LENGTH_SHORT = 5;
//private static final String SERVER_RES_SIGN_UP_FAILED = "0";
private static final String SERVER_RES_RES_SIGN_UP_SUCCESFULL = "1";
private static final String SERVER_RES_SIGN_UP_USERNAME_CRASHED = "2";
private EditText usernameText;
private EditText passwordText;
private EditText eMailText;
private EditText passwordAgainText;
private Manager imService;
private Handler handler = new Handler();
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
imService = ((MessagingService.IMBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
imService = null;
Toast.makeText(SigningUp.this, R.string.local_service_stopped,
Toast.LENGTH_SHORT).show();
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signingup);
setTitle("Sign up");
Button signUpButton = (Button) findViewById(R.id.signUp);
Button cancelButton = (Button) findViewById(R.id.cancel_signUp);
usernameText = (EditText) findViewById(R.id.userName);
passwordText = (EditText) findViewById(R.id.password);
passwordAgainText = (EditText) findViewById(R.id.passwordAgain);
eMailText = (EditText) findViewById(R.id.email);
signUpButton.setOnClickListener(new OnClickListener(){
public void onClick(View arg0)
{
if (usernameText.length() > 0 &&
passwordText.length() > 0 &&
passwordAgainText.length() > 0 &&
eMailText.length() > 0
)
{
//TODO check email address is valid
if (passwordText.getText().toString().equals(passwordAgainText.getText().toString())){
if (usernameText.length() >= 5 && passwordText.length() >= 5) {
Thread thread = new Thread(){
String result = new String();
#Override
public void run() {
result = imService.signUpUser(usernameText.getText().toString(),
passwordText.getText().toString(),
eMailText.getText().toString());
handler.post(new Runnable(){
public void run() {
if (result.equals(SERVER_RES_RES_SIGN_UP_SUCCESFULL)) {
Toast.makeText(getApplicationContext(),R.string.signup_successfull, Toast.LENGTH_LONG).show();
//showDialog(SIGN_UP_SUCCESSFULL);
}
else if (result.equals(SERVER_RES_SIGN_UP_USERNAME_CRASHED)){
Toast.makeText(getApplicationContext(),R.string.signup_username_crashed, Toast.LENGTH_LONG).show();
//showDialog(SIGN_UP_USERNAME_CRASHED);
}
else //if (result.equals(SERVER_RES_SIGN_UP_FAILED))
{
Toast.makeText(getApplicationContext(),R.string.signup_failed, Toast.LENGTH_LONG).show();
//showDialog(SIGN_UP_FAILED);
}
}
});
}
};
thread.start();
}
else{
Toast.makeText(getApplicationContext(),R.string.username_and_password_length_short, Toast.LENGTH_LONG).show();
//showDialog(USERNAME_AND_PASSWORD_LENGTH_SHORT);
}
}
else {
Toast.makeText(getApplicationContext(),R.string.signup_type_same_password_in_password_fields, Toast.LENGTH_LONG).show();
//showDialog(TYPE_SAME_PASSWORD_IN_PASSWORD_FIELDS);
}
}
else {
Toast.makeText(getApplicationContext(),R.string.signup_fill_all_fields, Toast.LENGTH_LONG).show();
//showDialog(FILL_ALL_FIELDS);
}
}
});
cancelButton.setOnClickListener(new OnClickListener(){
public void onClick(View arg0)
{
finish();
}
});
}
protected Dialog onCreateDialog(int id)
{
switch (id)
{
case TYPE_SAME_PASSWORD_IN_PASSWORD_FIELDS:
return new AlertDialog.Builder(SigningUp.this)
.setMessage(R.string.signup_type_same_password_in_password_fields)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked OK so do some stuff */
}
})
.create();
case FILL_ALL_FIELDS:
return new AlertDialog.Builder(SigningUp.this)
.setMessage(R.string.signup_fill_all_fields)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked OK so do some stuff */
}
})
.create();
case SIGN_UP_FAILED:
return new AlertDialog.Builder(SigningUp.this)
.setMessage(R.string.signup_failed)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked OK so do some stuff */
}
})
.create();
case SIGN_UP_USERNAME_CRASHED:
return new AlertDialog.Builder(SigningUp.this)
.setMessage(R.string.signup_username_crashed)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked OK so do some stuff */
}
})
.create();
case SIGN_UP_SUCCESSFULL:
return new AlertDialog.Builder(SigningUp.this)
.setMessage(R.string.signup_successfull)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
finish();
}
})
.create();
case USERNAME_AND_PASSWORD_LENGTH_SHORT:
return new AlertDialog.Builder(SigningUp.this)
.setMessage(R.string.username_and_password_length_short)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked OK so do some stuff */
}
})
.create();
default:
return null;
}
}
#Override
protected void onResume() {
bindService(new Intent(SigningUp.this, MessagingService.class), mConnection , Context.BIND_AUTO_CREATE);
super.onResume();
}
#Override
protected void onPause()
{
unbindService(mConnection);
super.onPause();
}
}
hey your problem is because of ImService object. its declaration in onResume method just move it to your onCreate because oncreate call before onresume method and your imService object use in oncreate.
bindService(new Intent(SigningUp.this, MessagingService.class), mConnection , Context.BIND_AUTO_CREATE);
put this line before buttononclicklistner.
I need to do some validations sequentially and some of them involve complex database operations.
So, I need to do this in a separated thread of UI Thread, ok?
But some validations show messages to user, what need confirmation and
when user confirm, the next validation should be call.
This code example explains what I want to implement:
void makeValidation1(){
if(condition1Valid()){
makeValidation2();
}else{
DialogInterface.OnClickListener onClick = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
makeValidation2();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setMessage("really want to do this?")
.setPositiveButton("Yes", onClick);
builder.create().show();
}
}
void makeValidation2(){
if(condition2Valid()){
}else{
//...
}
}
boolean condition1Valid() {
// complex database Operations
return false;
}
boolean condition2Valid() {
//complex database Operations
return false;
}
//...
void makeValidation9(){
//...
}
My question is: What the best way/pattern to implement this?
1 - Create one asyncTask for each validation? (I cant create only one AsyncTask, because confirmation messages can stop flux).
2 - Create a Runnable for each validation and create thread to run that when need call next validation?
3 - ???
edit
I tested this code #BinaryBazooka, but isnt work. Any help?
public class MainActivity extends Activity implements OnClickListener {
Thread mThread;
ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button = new Button(this);
button.setText("Start");
setContentView(button, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
mThread = new Thread(new Runnable() {
#Override
public void run() {
validations();
}
});
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Start Thread?");
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.show();
mThread.run();
}
});
builder.create().show();
}
void validations(){
//this method go on separated thread
validation1();
validation2();
validation3();
}
void validation1(){
if(true){
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("Validation 1 failed. Go validation 2?");
builder.setPositiveButton("Go", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mProgressDialog.show();
//if user confirm, continue validation thread
mThread.notify();
}
});
builder.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
//if user cancel, stop validation thread
mThread.interrupt();
}
});
runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressDialog.hide();
builder.create().show();
}
});
try {
synchronized (mThread) {
//wait for user confirmation
mThread.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void validation2() {
if(true){
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("validacao 2 failed. Go validation 3?");
builder.setPositiveButton("Go", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mProgressDialog.show();
mThread.notify();
}
});
builder.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
mThread.interrupt();
}
});
runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressDialog.hide();
builder.create().show();
}
});
try {
synchronized (mThread) {
mThread.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void validation3() {
Log.i("TAG", "<<<<<<<<<< >>>>>>>>>>>>");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "finished", Toast.LENGTH_SHORT);
}
});
}
}
I would create a new thread and sleep it during these dialog calls, you can access the UI directly from within your runnable with..
runOnUiThread(new Runnable() {
public void run() {}
});
So something like..
Thread someThread = new Thread(new Runnable() {
#Override
public void run(){
runOnUiThread(new Runnable() {
public void run()
{
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(R.string.msg);
builder.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
someThread.notify();
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
someThread.wait();
Works with AsyncTask. Ty.
Code:
public class MainActivity extends Activity implements OnClickListener {
//Thread mThread;
ProgressDialog mProgressDialog;
private ValidationsAsyncTask async;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button = new Button(this);
button.setText("Start");
setContentView(button, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Start Thread?");
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.show();
async = new ValidationsAsyncTask();
async.execute();
}
});
builder.create().show();
}
void validation1(){
if(true){
runOnUiThread(new Runnable() {
#Override
public void run() {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("Validation 1 failed. Go validation 2?");
builder.setPositiveButton("Go", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mProgressDialog.show();
//if user confirm, continue validation thread
synchronized (async) {
async.notify();
}
}
});
builder.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
//if user cancel, stop validation thread
async.cancel(true);
}
});
mProgressDialog.hide();
builder.create().show();
}
});
Log.i("TAG - validation1", Thread.currentThread().getName());
try {
synchronized (async) {
//wait for user confirmation
async.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void validation2() {
if(true){
runOnUiThread(new Runnable() {
#Override
public void run() {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("validacao 2 failed. Go validation 3?");
builder.setPositiveButton("Go", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mProgressDialog.show();
synchronized (async) {
async.notify();
}
}
});
builder.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
async.cancel(true);
}
});
mProgressDialog.hide();
builder.create().show();
}
});
try {
synchronized (async) {
async.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void validation3() {
runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressDialog.dismiss();
Toast.makeText(MainActivity.this, "finished", Toast.LENGTH_SHORT).show();
}
});
}
class ValidationsAsyncTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
validation1();
validation2();
validation3();
return null;
}
#Override
protected void onCancelled() {
Toast.makeText(MainActivity.this, "cancelled", Toast.LENGTH_LONG).show();
}
}
}