Progress Bar with countdown timer in android - android-layout

I need a progress bar in my layout, which will have a total time of 30 secs and will tick every second. Basically I want the user of my app to see that he has 30 sec time before time is up.
This is the piece of code I have written.
But this gives me a blank progress bar with no activity. Please help.
What am I doing wrong
public class MySeekBarActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setProgressBarVisibility(true);
final ProgressBar progressHorizontal = (ProgressBar) findViewById(R.id.progress_horizontal);
progressHorizontal.setProgress(progressHorizontal.getProgress()* 100);
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
progressHorizontal.incrementProgressBy(1);
int dtotal = (int) ( 30000 - millisUntilFinished ) /30000 * 100;
progressHorizontal.setProgress(dtotal);
}
public void onFinish() {
// DO something when 2 minutes is up
}
}.start();
}
}

You've got a type conversion bug, due to two things:
you're dividing by an int, which causes the decimal to be rounded down,
also, you're casting the result too early, so even if you'd divide by a float/double, the result would get rounded down anyway.
To see what I mean - you can safely remove the cast to int from your code, and it will compile anyway. That means your final number is an int, and since you're not making any casts earlier, it means you're losing the decimal info pretty early on in the code.
This is a possible fix:
int dtotal = (int) (( 30000 - millisUntilFinished ) /(double)30000 * 100);
to resolve such bugs in the future, make a dummy Java program with a loop containing the equation, and print out the intermediate result, for example:
public class NumberTester {
//define the constants in your loop
static final int TOTAL_TIME = 30000;
static final int INTERVAL = 1000;
public static void main(String[] args) {
//perform the loop
for(int millisUntilFinished = TOTAL_TIME;millisUntilFinished >=0;millisUntilFinished -= INTERVAL) {
int dtotal = (int) (( TOTAL_TIME - millisUntilFinished ) /(double)TOTAL_TIME * 100);
System.out.println(dtotal);
}
}
}
Also, some important things:
don't start your timer in onCreate - your activity is not visible yet at this point! Use onResume instead.
kill your timer in onPause. Leaving timers and threads unmanaged like that is bad form, and may lead to weird bugs.
don't use "magic numbers". Place all your constant values in a static final class members, like I've done in the example. This will save you a lot of headaches when you decide to change those values.
EDIT: as to why your progress bar stops short of completion, that's because the onTick method works a bit differently than you're probably assuming it does. To see what I mean, add:
System.out.println("Milis:" + millisUntilFinished);
System.out.println("dtotal:" + dtotal);
to your onTick method. The values clearly don't count down to 0 (and hence 100 in the case of dtotal, it being derived from millisUntilFinished) - you have to compensate for that.

Related

How to print the progress of cython's prange?

I'm using prange for parallelizing a loop in my cython code. As this loop takes a long time, I want to print its progress as it goes. A progress bar would be nice but anything that shows the progress would do. I tried to add some form of logging in the following fashion:
for index in prange(n, nogil = True, num_threads = 5):
if index == (index//1000)*1000:
printf("%d percent done", index*100/n)
This should print the progress whenever index % 1000 == 0.
The output of this is kind of random.
0 percent done
80 percent done
20 percent done
100 percent done
60 percent done
I assume that this is because prange does not assign threads to indexes starting from 0 and going up.
Is there any way to implement such a thing in Cython?
Thanks!
There are probably ways in Cython to achieve what you want, however I find it easier to use OpenMP from C/C++ and to call the functionality from Cython (thanks to C-verbatim-code since Cython 0.28 it is quite convenient).
One thing is clear, to achieve your goal you need some kind of synchronization between threads, which might impact performance. My strategy is simple: every thread reports "done", all done task are registered and they number is reported from time to time. The count of reported tasks is protected with a mutex/lock:
%%cython -c=/openmp --link-args=/openmp
cdef extern from * nogil:
r"""
#include <omp.h>
#include <stdio.h>
static omp_lock_t cnt_lock;
static int cnt = 0;
void reset(){
omp_init_lock(&cnt_lock);
cnt = 0;
}
void destroy(){
omp_destroy_lock(&cnt_lock);
}
void report(int mod){
omp_set_lock(&cnt_lock);
// start protected code:
cnt++;
if(cnt%mod == 0){
printf("done: %d\n", cnt);
}
// end protected code block
omp_unset_lock(&cnt_lock);
}
"""
void reset()
void destroy()
void report(int mod)
from cython.parallel import prange
def prange_with_report(int n):
reset() # reset counter and init lock
cdef int index
for index in prange(n, nogil = True, num_threads = 5):
report(n//10)
destroy() # release lock
Now calling: prange_with_report(100) would print done: 10\n, done: 20\n, ..., done: 100\n.
As a slight optimization, report could be called not for every index but only for example for index%100==0 - there will be less impact on the performance but also the reporting will be less precise.

Why is this code not thread-safe even though an AtomicInteger is used to track progress?

I tried making a class that extends thread which simply takes an array of strings and prints the first 2 strings out alternately for 10000 iterations. I keep track of the index to print from using an AtomicInteger (counter), however the output sometimes prints this:
hello
hello
hello
w
hello
hello
etc.
instead of alternating at each iteration. Why is this and how could I fix it without just putting 'synchronized' in the run method?
public class MyThreadDelegate implements Runnable {
List<String> words;
AtomicInteger counter = new AtomicInteger(0);
public MyThread(List<String> words) {
this.words = words;
}
#Override
public void run() {
for (int i = 0; i < 10000; i++) {
System.out.println(words.get(counter.getAndIncrement()%2) + counter.get());
}
}
public static void main(String[] args) {
MyThreadDelegate myThreadDelegate = new MyThreadDelegate(Arrays.asList("hello", "w"));
Thread t1 = new Thread(MyThreadDelegate);
Thread t2 = new Thread(MyThreadDelegate);
t1.start();
t2.start();
}
}
While the numbers are retrieved one by one, the rest of the method isn't synced up. So sometimes this might happen:
t1: gets value 0 from the counter
t2: gets value 1 from the counter
t2: prints w
t1: prints hello
A quick fix would be to put the whole System.out line in a synchronized block, but that would not guarantee that the threads take turns. It just guarantees that echt value is retrieved, incremented and printed before the next one.
If you want to have the threads actually take turns, you'll have to implement some sort of locking. But if you wan't to have the threads wait for each other, why are you using multiple threads?
EDIT: also, you should probably have MyThread implement Runnable instead of extending Thread if you're going to use it this way. See this link for more: https://www.baeldung.com/java-runnable-vs-extending-thread (Solomon Slow beat me to it :)

The value is not taken from the dictionary in JMH when thread is 2?

For a JMH class, Thread number is limited to 1 via #Threads(1).
However, when I get the number of threads using Thread.activeCount(), it shows that there are 2 threads.
The simplified version of the code is below:
#Fork(1)
#Warmup(iterations = 10)
#Measurement(iterations = 10)
#BenchmarkMode(Mode.AverageTime)
#OutputTimeUnit(TimeUnit.MICROSECONDS)
#Threads(1)
public class MyBenchmark {
#State(Scope.Benchmark)
public static class BState {
#Setup(Level.Trial)
public void initTrial() {
}
#TearDown(Level.Trial)
public void tearDownTrial(){
}
}
#Benchmark
public List<Integer> get(BState state) {
System.out.println("Thread number: " + Thread.activeCount());
...
List<byte[]> l = new ArrayList<byte[]>(state.dict.get(k));
...
}
}
Actually, the value is tried to get from the dictionary using its key. However, when 2 threads exist, the key is not able to get from the dictionary, and here list l becomes [].
Why the key is not taken? I limit the thread number because of this to 1.
Thread.activeCount() answers the number of threads in the system, not necessarily the number of benchmark threads. Using that to divide the work between the benchmark threads is dangerous because of this fundamental disconnect. ThreadParams may help to get the benchmark thread indexes, if needed, see the relevant example.
If you want a more conclusive answer, you need to provide MCVE that clearly highlights your problem.

constant expression required while using constants

private static int counter = 0; public static final int
CLIENT_REQUEST_TIME = counter++;
...
switch (command) { case Command.CLIENT_REQUEST_TIME:
...
but here it comes the
"Error:(20, 25) java: constant expression required",
for the case statement.
but why on earth? since CLIENT_REQUEST_TIME is constant
I know this is something that should be rather addressed to Oracle and I can choose from millions of workarounds... but just in case someone can see some logic behind, it will certainly make me sleep better tonight :)
This error comes because you set not constant property to constant field. I am not understand what this code must to do, but possibly you can change it to look like this:
private static int counter = 0;
public static int CLIENT_REQUEST_TIME = counter++;

Is threading not working properly in Nunit?

I think that nunit isn't function properly when threading code is involved:
Here's the sample code:
public class multiply
{
public Thread myThread;
public int Counter
{
get;
private set;
}
public string name
{
get;
private set;
}
private Object thisLock = new Object();
public void RunConsolePrint()
{
//lock(thisLock)
//{
Console.WriteLine("Now thread " + name + " has started");
for (int i = 1; i<= Counter; i++)
{
Console.WriteLine(name + ": count has reached " + i+ ": total count is "+Counter);
}
Console.WriteLine("Thread " + name + " has finished");
//}
}
public multiply(string pname, int pCounter)
{
name = pname;
Counter = pCounter;
myThread = new Thread(new ThreadStart(RunConsolePrint));
}
}
And here's the test code:
[Test]
public void Main()
{
counter=100;
multiply m2=new multiply("Second", counter);
multiply m1 = new multiply("First", counter);
m1.myThread.Start();
m2.myThread.Start();
}
And the output is a sequential running of m1 and m2, which means that the loop in m1 is always execute first before m2, at least that's what my testing shows. I ran the tests a few times and I always get this.
Is this a bug? Or an expected behavior?
If I copy the above code to a console program and run, I can see the threading effect clearly.
I am using the test using TestDriven.net runner.
The exact interleaving of two or more threads cannot really be predicted.
There are a couple of factors to consider for your example. First of all each thread will execute for its quantum before (potentially) getting switched to another thread. You can't expect thread switches to happen on any special place in your code. I.e. one thread might finish before the other one is started (especially since the task is relatively short in your case).
Secondly, since you're writing to the console, the threads are synchronized on that access. This also affects the interleaving.
The result also depends on the number of available core on your machine (as well as the general load on the machine when you run the code).
In short, you cannot predict how the two threads will run.
It's non-deterministic whether m1 or m2 starts executing first. If the counter executes fast enough, I wouldn't be surprised to see one of them finish before the other starts. Change the count to something very large (e.g. a million) and I'm pretty sure you'll see separate threads executing concurrently.
Any result is possible - what result are you seeing that suggests there's a bug?

Resources