I have a thread in Activity A which starts Activity B after 30 seconds.But user can also go to activity B before that time on a button click.I want kill thread in Activity A if the user clicks that button so that Activity B wont get started again. I tried to kill thread if button is clicked, but it is of no use and finish() is also not killing that thread after navigating to B.
Thread t=new Thread()
{
public void run()
{
try {
sleep(5000);
currentClass = Class.forName("com.crazydna.memorizethepic.Level"+levelNumber);
Intent ourIntent = new Intent(PictureDisplay.this, currentClass);
startActivity(ourIntent);
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
Log.e("TAG","Error: " +e.getStackTrace());
//e.printStackTrace();
AlertDialog.Builder alertDialog=new AlertDialog.Builder(PictureDisplay.this);
alertDialog.setTitle("Alert!!!");
alertDialog.setMessage(" "+e.toString());
alertDialog.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
alertDialog.show();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
AlertDialog.Builder alertDialog=new AlertDialog.Builder(PictureDisplay.this);
alertDialog.setTitle("Alert!!!");
alertDialog.setMessage(" "+e.toString());
alertDialog.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
};
t.start();
just put a boolean variable isStarted as instance variable, Check this within thread
try {
sleep(5000);
if(!isStarted)
{
currentClass =
Class.forName("com.crazydna.memorizethepic.Level"+levelNumber);
Intent ourIntent = new Intent(PictureDisplay.this, currentClass);
startActivity(ourIntent);
}
}
On button click set isStarted to true
You have to options.
The first option is to shorten the time for your sleep() function and enclose it in a while() block where you monitor a cancellation variable, this variable would be in your class definition.
Boolean run_my_timer = true;
while (run_my_timer)
{
sleep(1000); // sleep 1 second only
currentClass = Class.forName("com.crazydna.memorizethepic.Level"+levelNumber);
Intent ourIntent = new Intent(PictureDisplay.this, currentClass);
startActivity(ourIntent);
}
And add a line that set's this variable to false if the user clicks the button
run_my_timer = false;
This would make the thread exit.
The second option, which would be more elegant is create a Timer, instead of a thread, if the user presses the button to open ActivityB you cancel the timer, with the Timer's cancel() method.
Related
I need to finish the execution of an async task before I make some checks for my login.
This is my async task
#Override
protected void onPostExecute(JSONArray jsonArray)
{
JSONObject json_data = null;
for (int i = 0; i < jsonArray.length(); i++) {
try {
json_data = jsonArray.getJSONObject(i);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
for (int j=0; j<jsonArray.length(); j++){
/*allMatrics.add(json_data.getString("matricNos"));
allPasswords.add(json_data.getString("password"));*/
if (user.equals(json_data.get("matricNos")) && pass.equals(json_data.get("password")))
{
ok = true;
System.out.println("hi i am ok");
break;
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Checking ok = "+ ok);
}
I need to finish this async task before I Check its status and then go on for my login authentication. It is supposed to be executed on the onclick of the login button
login.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
user = uedit.getText().toString();
pass = pedit.getText().toString();
if (user.equals(""))
{
Toast error = Toast.makeText(LogInScreen.this, "Enter Details", Toast.LENGTH_SHORT);error.show();
}
else
{
final GetMatricNos mat = new GetMatricNos();
mat.execute(new ServerConnector());
// have to finish task before enter user, have to implement logout as well
if ((mat.getStatus().equals(AsyncTask.Status.RUNNING))) - This has to be Status.FINISHED
{
System.out.println(ok);
/* if ((allMatrics.contains(user) && (allPasswords.contains(pass)))) */
if (ok)
{
Intent homescreen = new Intent(LogInScreen.this, HomeScreen.class);
homescreen.putExtra("username", user);
startActivity(homescreen);
}
else
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(LogInScreen.this);
alertDialogBuilder.setTitle(Html.fromHtml("<font color='#D41E46'>Invalid Login Details</font>"));
alertDialogBuilder
.setMessage("The login credentials you have entered are invalid. Please try again.")
.setIcon(R.drawable.alert)
.setCancelable(false)
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
}
}
});
ActionBar actionBar = getActionBar();
actionBar.hide(); // To hide the actionBar on LoginScreen
}
Now If I don't finish the task before checking it, it won't let me check the credentials that I am getting from the edit boxes, however first time if I login it doesn't make the check because the task runs when the login button is pressed, but for the second time if I login it goes through...?
Any help would be much appreciated, I tried task.cancel(true) before the check but that doesnt help...
If your task needs to finish executing before you do anything else then you must put the code that must wait in your onPostExecute which gets called when the task is finished
How create a button which pause the thread which is inside the loop and another button which
resumes.
Runnable myRun = new Runnable(){
public void run(){
for(int j =0 ;j<=words.length;j++){
synchronized(this){
try {
wait(sleepTime);
bt.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}});
bt2.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
notify();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} }
runOnUiThread(new Runnable(){
public void run(){
try {
et.setText(words[i]);
i++;
} catch (Exception e) {
e.printStackTrace();
}
}});
}}};
doing some stuff say words.lenght=1000 times
then suppose user want to take break in between
click pause button with id = bt this button pauses thread until and user
clicks resume with id= bt1
Below is a hint , i think you can use for your problem. Its copied from the link i pasted at end.
A wait can be "woken up" by another process calling notify on the monitor which is being waited on whereas a sleep cannot. Also a wait (and notify) must happen in a block synchronized on the monitor object whereas sleep does not:
Object mon = ...;
synchronized (mon) {
mon.wait();
}
At this point the currently executing thread waits and releases the monitor. Another thread may do
synchronized (mon) { mon.notify(); }(On the same mon object) and the first thread (assuming it is the only thread waiting on the monitor) will wake up.
Check Difference between wait() and sleep()
You do it like this:
How to indefinitely pause a thread in Java and later resume it?
Only you call the suspend() and other methods from your buttons' OnClickListeners
I am trying to wait untill the spalsh screen will be over abd then when get the result from splash go to anther activity bu my code not wating for splash (AsyncTask) just going for what after to intent.
Hope you can help.
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String nextActivity=new String();
Thread splashTread = new Thread() {
#Override
public void run() {
try {
splash splash=(tools.splash) new splash(first.this).execute();
int waited = 0;
while(splash.running && (waited< getResources().getInteger(R.integer.splashTimeOut)))
{
sleep(100);
if(splash.running) {
waited += 100;
}
// nextActivity=splash.newActivity;
}
Intent intent = new Intent(first.this,Class.forName("activities.third"));
startActivity(intent);
} catch(InterruptedException e) {
// do nothing
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
finish();
}
}
};
splashTread.start();
try {
Intent intent = new Intent(first.this,Class.forName("activities.third"));
startActivity(intent);
Use this code
Intent intent = new Intent(first.this,Class.forName("activities.third"));
startActivity(intent);
inside finally before finish() instead of start try block;
Im Adding Progress Dialog in some Activity .But im getting Exception mention in title.how to resolve it.
dialog = ProgressDialog.show(Notification.this, "loading please wait",
"Loading. Please wait...", true);
new Thread() {
public void run() {
try{
performBackgroundProcess1();
//sleep(3000,000);
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
// dismiss the progress dialog
dialog.dismiss();
}
}.start();
Any thing wrong with this.all Background process is performed in performbackgroundprocess method.
You cant call dialog.dismiss(); in the background thread.
You can make Threads send messages to handlers when they are done and in the handler you can dismiss the dialog. Handlers work in ui thread
There is a tutorial about it
use runOnUiThread as:
new Thread() {
public void run() {
try{
performBackgroundProcess1();
//sleep(3000,000);
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
// dismiss the progress dialog
CurrentActivity.this.runOnUiThread(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
}
}.start();
i am calling this function from the menu and calls the upload(item) function to pass the index of the selected priority.
public void showPriorityDialog()
{
final CharSequence[] priority = {"1 Hour", "12 Hours", "24 Hours", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select Priority");
builder.setItems(priority, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if(item != 3)
upload(item);
}
});
AlertDialog alert = builder.create();
alert.show();
}
however, whenever i call the upload function, the thread doesn't run in background, and the OS thinks that the app is not responding due to executing timeout.
public void upload(int priority)
{
final int _priority = priority;
uploadThread = new Thread()
{
#Override
public void run()
{
try
{
super.run();
mHandler.post(new Runnable() {
#Override
public void run() {
try
{
//ftp commands...
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), e.toString() , Toast.LENGTH_SHORT).show();
}
}
});
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), e.toString() , Toast.LENGTH_SHORT).show();
}
}
};
uploadThread.start();
}
am i doing something wrong? TIA
When you do mHandler.post(), your entire Runnable executes on UI thread and your background thread just exits. To fix, do FTP before posting to handler. Then do mHandler.post() to have Toast appear. Note that you catch also need to display Toast via post.