Two things are supposed to happen inside the following method. The ProgressBar is supposed to be set to 100% and a layout is supposed to be visible. But on calling the method, the layout gets visible but the ProgressBar does not change its value.
I must add that this is a file sharing app and the ProgressBar becomes 100% on the client side of the code, the problem is on the server. Although both the codes are the same.
ServerClass_Activity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mWaveLoadingView.setProgressValue(100);
mWaveLoadingView.setCenterTitle("100%");
meowLayout.setVisibility(View.VISIBLE);
}
});
There is a handler running that updates the ProgressBar for a certain time.
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
Log.d( "","entered run ");
mWaveLoadingView.setCenterTitle(String.valueOf(progress)+"%");
mWaveLoadingView.setProgressValue(progress);
progress+=1;
if(progress==90 || finished == true)
stopRepeatingTask();
} finally {
if(progress<90 && finished == false)
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
The variable finished becomes true when the file is sent successfully.
Any idea why the ProgressBar is not being 100%?
Related
I created one handler to repeat a task repeatedly and I also want to destroy it within that handler once a condition has been met.
pinHandler = new Handler();
Now I created two functions separately to start and stop the task.
void startRepeatingPins() {
mPinSetter.run();
}
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
try{
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
}
}
finally {
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
private void stopUpdatingPins()
{
pinIndexCount=0;
pinHandler.removeCallbacks(mPinSetter);
System.out.println("Called the stop function.");
}
Now, the issue is that, if I call the stopUpdatingPins function , the handler stops but when I try to stop it automatically from within the handler, it just doesn't stop. Although the stopUpdatingPins function does get called.
Change You startRepeatingPins() like this, You should not directly call the run. If your run like this then there is no point of removing this from Handler. So attach Runnable with Handler.
void startRepeatingPins() {
pinHandler.post(mPinSetter);
}
You added post delay in finally that means you are stopping at first if loop and starting again in finally, So it's never stopping. So Change your runnable like this,
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
The title says it all. I want to make a view into an infinite loop of random visibility and invisibility. This is how I approached it :-
First I created two methods to get Random time getRandomWaitTime() and getRandomDisplayTime(). These methods are well defined and tested (in Log) and are working as desired. Both these methods return a random value as int in millisecond as
getRandomWaitTime() : 3000-6000
getRandomDisplayTime() : 3000-5000
Now I created one ImageView fruit[0], set it initially as invisible and after that the following code is executed :
fruit[0].postDelayed(new Runnable() {
#Override
public void run() {
fruit[0].setVisibility(View.VISIBLE);
fruit[0].postDelayed(new Runnable() {
#Override
public void run() {
fruit[0].setVisibility(View.INVISIBLE);
}
}, getRandomDisplayTime());
fruit[0].postDelayed(this, getRandomWaitTime());
}
}, getRandomWaitTime());
The code compiles, executes as well, the ImageView goes through infinite cycle of visibility and invisibility but the time for which it is set as visible or invisible doesn't seem to have minimum value of 3000ms Sometimes it feels like it is visible for a 500ms and then gone invisible. I have tried a ton of things such as using Handler.postDelayed instead of View.postDelayed but this doesn't seem to work.
Interesting thing happens when I remove all getRandomWaitTime() and getRandomDisplayTime() methods from postDelayed method and replace then with a constant like 3000.
The activity starts. At first fruit[0] is set to invisible. After 3000ms it comes visible and stays there. Nothing happens after it. No more switching to invisibility. I just stays there.
So what could be the possible reasons for all these sorcery problems?
The point is that, after the first
you call fruit[0].setVisibility(View.VISIBLE);:
fruit[0].postDelayed(new Runnable() {
#Override
public void run() {
fruit[0].setVisibility(View.INVISIBLE);
}
}, getRandomDisplayTime());
and:
fruit[0].postDelayed(this, getRandomWaitTime());
are executed almost at the same time (immediately).
So, let's say for example the getRandomDisplayTime() return 3000 and getRandomWaitTime() returns 3500, you will see the view visible after 3000 milliseconds and after 500 milliseconds more, it will disappear again.
You can change your code in this way:
fruit[0].postDelayed(new Runnable() {
#Override
public void run() {
final Runnable runnable = this;
fruit[0].setVisibility(View.VISIBLE);
fruit[0].postDelayed(new Runnable() {
#Override
public void run() {
fruit[0].setVisibility(View.INVISIBLE);
fruit[0].postDelayed(runnable, getRandomWaitTime());
}
}, getRandomDisplayTime());
}
}, getRandomWaitTime());
Your code is a bit messy, try this example. Based on the view itself, values will be chosen instead of nested postDelayed() methods.
fruit[0].postDelayed(new Runnable() {
#Override
public void run() {
fruit[0].setVisibility(backButton.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE);
fruit[0].postDelayed(this, backButton.getVisibility() == View.VISIBLE ? getRandomDisplayTime() : getRandomWaitTime());
}
}, fruit[0].getVisibility() == View.VISIBLE ? getRandomDisplayTime() : getRandomWaitTime());
I've got a listView that gets populated from a server. In the onClick of the ListItem, I display a button for a x number of seconds and I make it invisible again. How can I reset the time every time the onClick is called?
Here is my listItem onClick:
private void displayInCallButton() {
mButton.setEnabled(true);
if (canDisplayInCallControlls) {
canDisplayInCallControlls = false;
fadeInAnimation(mButton);
mButton.setEnabled(true);
mFrontView.postDelayed(new Runnable() {
public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
}, 5000);
}
}
Thank you in advance.
You have to remove the callbacks and set it once again with the new one with the reset time.
first, set the call back like
Runnable myRunnable = new Runnable() {
#Override
public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
};
then set it to mFrontView like,
mFrontView.postDelayed(myRunnable,5000)
If you want to reset, do it like
mFrontView.removeCallbacks(myRunnable);
mFrontView.postDelayed(myRunnable, 2000);
How can I reset the time every time the onClick is called?
There is no built-in mechanism to accomplish that.
You can, however, keep a reference to the Runnable you post, remove it and then repost it again to restart at the original delay.
The result would look somewhat like this in its most simple form:
Runnable mDelayedRunnable = new Runnable() {
#Override public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
};
private void displayInCallButton() {
mButton.setEnabled(true);
if (canDisplayInCallControlls) {
canDisplayInCallControlls = false;
fadeInAnimation(mButton);
mButton.setEnabled(true);
mFrontView.removeCallbacks(mDelayedRunnable);
mFrontView.postDelayed(mDelayedRunnable, 5000);
}
}
You can safely call removeCallbacks() with a Runnable that was never posted in the first place (or even null).
If you don't want to keep an explicit reference to the Runnable, you could also opt to tag the view with it. Just don't forget to clean up on i.e. orientation changes and the like.
I finally got my app working, i just have one issue which i would like to correct.
I have a button which controls a thread that runs a couple function in the background. The functions in the background eventually stop the thread whenever a certain value is reached. What i am having issues doing is pressing that same button again to just stop the thread manually. Currently I can only start the thread and wait for itself to finish. I am able to do other things in the app, so the thread is running on its own, i just want to kill it manually.
public void onMonitorClick(final View view){
if (isBLEEnabled()) {
if (!isDeviceConnected()) {
// do nothing
} else if (monitorvis == 0) {
showMonitor();
DebugLogger.v(TAG, "show monitor");
//monitorStop = 4;
Kill.runThread(); // I want a function here that would kill the
// thread below, or is there something that
// can be modified in runThread()?
// I did try Thread.Iteruppted() without luck
shutdownExecutor();
} else if (monitorvis == 1) {
hideMonitor();
DebugLogger.v(TAG, "hide monitor");
monitorStop = 0;
runThread(); //The running thread that works great on its own
}
}
else {
showBLEDialog();
}
}
private void runThread() {
new Thread() {
int i;
public void run() {
while (monitorStop != 3) { //This is where the thread stops itself
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
((ProximityService.ProximityBinder) getService()).getRssi();
rssilevel = ((ProximityService.ProximityBinder) getService()).getRssiValue();
mRSSI.setText(String.valueOf(rssilevel) + "dB");
detectRange(rssilevel);
}
});
Thread.sleep(750);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
On first look, you could simply set monitorStop = 3, which would cause the thread to eventually stop after it's timeout completes.
The problem with this, is that I presume if you push the button again or your code modifies monitorStop at some point in the future, then the thead you wanted dead, might stay alive. ie: monitorStop will need to stay equal to three for at least 750ms to assure the thread will comlete it's loop and die.
The correct way to do this would be to create your thread as a new class with it's own monitorStop parameter. When you create the thread, you would keep a reference to it and modify the thread's monitorStop parameter. This way the thread would finish without interruption. If you wanted to create a new thread, then this would not affect the old thread from finishing appropriately.
I've got a Thread parsing XML in the background of my app. As it does so, it updates a progress bar in the activity's view via a Handler. This works fine until the phone changes orientation (and probably during other destructive actions, like multitasking, though I haven't throughly tested there). After any number of rotations, the progress bar freezes where it is and never progresses, even when the parsing is done and my ListView updates itself just fine.
Here's a cut-down version of the relevant code. I'm not including it here, but I do have code in place to make sure the thread is continuing unencumbered after the rotation--like I said, the parsing eventually finishes and updates the ListView in the same amount of time. It's just the progress bar handler that doesn't work:
private ProgressBar mProgress;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.directory_list);
mProgress = (ProgressBar) findViewById(R.id.progressBar);
mProgress.setMax(entryCount);
startXMLParseThread();
}
private void startXMLParseThread() {
new Thread () {
Handler hUpdateProgressBar = new Handler(){
public void handleMessage(Message msg) {
mProgress.setProgress(entryCount);
}
};
public void run() {
while (parserEvent != XmlPullParser.END_DOCUMENT) {
entryCount++;
hUpdateProgressBar.sendEmptyMessage(0);
parserEvent = parser.next();
}
mHandler.post(new Runnable() {
public void run() {
adapter.getCursor().requery();
}
});
}
}.start();
}
May be its running the onCreate method again on orientation change ...so it loses reference to previous handler...try this ..add attribute to the manifest file in that particular activity android:configChanges="orientation"...in this way it wont run onCreate again...give it a shot...