New to Android: App Crashes When Running While Loop (Threading?) - java

I am trying to write and application which, when a button is pressed, will display all the prime numbers from 23 to 499. Now, I know I have my algorithm correct, so that is not the issue as I can run it using S.o.pln in some other Java Development program. The issue I believe lies in my use of a thread as I've never used one before, or maybe my use of a runnable. I could also be where I am appending an integer to a TextView, but, as I am new, I have no idea. Any help is greatly appreciated and if you need anymore context I will be happy to provide it. Thanks...
public class PrimeNumbers extends Activity implements OnClickListener {
Button whatPrime, howManyPrime, resetPrime;
TextView numPrime, ctPrime;
int prime = 23, factor, ct = 0;;
StringBuilder strBuPrime;
String strPrime;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.primenumbers);
initialize();
whatPrime.setOnClickListener(this);
howManyPrime.setOnClickListener(this);
resetPrime.setOnClickListener(this);
}// end onCreate
private void initialize() {
// TODO Auto-generated method stub
whatPrime = (Button) findViewById(R.id.bPrime);
howManyPrime = (Button) findViewById(R.id.bPrimeCount);
resetPrime = (Button) findViewById(R.id.bPrimeReset);
numPrime = (TextView) findViewById(R.id.tvPrimeNumbers);
ctPrime = (TextView) findViewById(R.id.tvPrimeNumbersCount);
}// end initialize
Runnable findPrimes = new Runnable() {
#Override
public void run() {
while (prime <= 499 && prime >= 23) {
factor = 3;
while (prime % factor != 0) // if true start testing
// other
// factors
{
while (factor <= (Math.sqrt(prime))) // testing
// other
// factors
{
if (prime % factor == 0) // factor found, leave
// while
{
factor = 2000;
}
factor++;
}
if (factor != 2001) // no factor found but left
// while, print
// prime, add 1 to counter
{
strPrime = Integer.toString(prime);
strBuPrime.append(strPrime + '\n');
}
factor = 1; // leave while as 1 is a factor of
// everything
}
prime += 2; // test next prime
}
numPrime.post(new Runnable() {
#Override
public void run() {
numPrime.setText(strBuPrime);
}
});
}
};
Thread threadPrimes = new Thread(findPrimes);
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()) {
case R.id.bPrime:
threadPrimes.start();
break;
case R.id.bPrimeCount:
ctPrime.setText("There are " + ct
+ " prime numbers from 23 to 499.");
break;
case R.id.bPrimeReset:
numPrime.setText("");
ctPrime.setText("");
break;
}
}// end onClick
}

logcat would help, but you are probably overdoing it with the post(Runnable) to append the values to your TextView. Try using a StringBuilder to concatenate everything and set the text all at once. (Or at least in larger chunks.)

You should try using AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html
I think your tread is still running in the UI threadpool and causes the UI to lockup.
Android will kill your thread if you lock the UI for ~2-3 seconds.
AsyncTask will also allow you to display a status bar or spinning ring while the runnable does the work.

Related

adding two decimals together giving truncated result when any value other than first value is not a whole number

I am attempting to create a calculator app, when I try to add 2 decimals together, I do not get the results I anticipated.
examples:
user inputs [1.1 + 1.1] and [1.1 + 1] or 2.1 is returned.
It is as if as if second value is being truncated, I am not entirely sure where this would be occurring
user inputs[2.1 + 2] and [2.1 + 2] or 4.1 is returned
user inputs [2 + 2.1] and [2 + 2] or 4 is returned
I have not used the debugger, though I have placed print line statements through out the code and I have not been able to see the issue.
Code:
information
I only attached a single number (image button) as all numbers 1-9 have identical code
variables that are not instantiated in code below have been instantiated as "" if they are a string and 0.0 if they are a double
I am using an array list called values which takes in strings, and using double.parsedouble() to convert it to a double, this occurs in the equals method
please let me know if their is anything I need to add to make this question easier to understand, and any help is appreciated
thank you!
1 button
one_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (plus_selected) {
update_selected_buttons(); //for boolean variables and to change mathematical function button image
screen_value = "";
updateScreen("1");
System.out.println(screen_value);
values.add(screen_value);
} else {
updateScreen("1");
System.out.println(screen_value);
}
}
});
addition button
addition_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!plus_selected) {
plus_selected = true;
addition_button_ET.setImageResource(R.drawable.addition_selected_500_500);
if(Double.parseDouble(screen_value) == current_value){
}
else
values.add(screen_value);//
} else {
plus_selected = false;
addition_button_ET.setImageResource(R.drawable.addition_button_500_500);
}
}
});
update screen
private void updateScreen(String value) { //being used for only one_button
//to reset title text
if (screen_value.equals(initial_screen_value)) {
screen_value = "0.0";
screen_TV.setTextSize(50);
}
//clears default value (0.0), allowing user to enter in a number
if (screen_value.equals("0.0")) {
screen_value = value;
screen_TV.setText(screen_value);
} else {
screen_value += value;
System.out.println(screen_value);
screen_TV.setText(screen_value);
}
}
clear button (clear button calls this method, and that is the only parameter it has)
private void resetScreen() {
screen_value = "0.0";
//values.clear();
screen_TV.setTextSize(50);
screen_TV.setText(screen_value);
}
equals button
equals_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
current_value = 0;
sum = 0;
System.out.println(values);
for(int i = 0; i<values.size();i++) {
sum += Double.parseDouble(values.get(i));
}
current_value = sum;
screen_value = "" + sum;
screen_TV.setText(screen_value);
}
});

How to set click limit of clicking a button? click limit is equal to score over 5

How can I set a limit of clicking a button? The number of click is equal to score % 5.Example score is equal to 15 the number of click limit is equal to 3 how can I do that? my codes is not working
int score = 0;
int help = score % 5;
if (score == help) {
helpbtn.setEnabled(false);
} else {
helpbtn.setEnabled(true);
}
I put it inside of
public void onClick(View v) { }
If in the example limit is 3, then :
if(help>0)
{
//logic;
help--;
}
you can add it in else block.
I think I understand what you need now. I've made some assumptions. I added a separate button to submit answers and I added a boolean that is always true for now. I did manage to use modulo in this version though. Hope this helps.
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private int score = 0;
private int help = 0;
private boolean answerCorrect = true; // dummy set always true for now
private Button answerButton = null;
private Button hlpbtn = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
answerButton = (Button)findViewById(R.id.button_answer);
answerButton.setOnClickListener(this);
hlpbtn = (Button)findViewById(R.id.button_help);
hlpbtn.setOnClickListener(this);
hlpbtn.setEnabled(false);
}
#Override
public void onClick(View view) {
if(view.getId() == R.id.button_answer) {
if(answerCorrect) {
if((++score % 5) == 0) {
++help;
}
if((help > 0) && !hlpbtn.isEnabled()) {
hlpbtn.setEnabled(true);
}
}
Log.d("Quiz", "score = " + score + ", help = " + help);
} else if(view.getId() == R.id.button_help) {
if(--help <= 0) {
hlpbtn.setEnabled(false);
Log.d("Quiz", "help button disabled");
}
Log.d("Quiz", "help pressed, " + help + " remaining");
}
}
}
It sounds like you want 15 / 5 instead of 15 % 5.
15 / 5 == 3, whereas 15 % 5 == 0.
15/5 =3. Try this, this will help you to click a button 3 times.
%it gives remainder. Ie --->15%5=0

Incrementing a value from $1 to $1.25 million with a timed interval as a Counter

Visualize this: The number starts from $0 and increments to $1.25 million and that incrementing process is shown on the UI using a timed interval between each increment (roughly 50-100 ms maybe?). I tried setting this up but sadly, the code below fails miserably.
double maxValue = 10;
double currentValue = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
//more code
value_text = (TextView) rootView.findViewById(R.id.value_text);
for (int i = 0; i < maxValue; i++) {
if (currentValue != maxValue) {
try {
currentValue++;
value_text.setText(String.valueOf(currentValue));
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Tricky Part: The textview will progress from $1 to $1.25 million, which means we are going to have to change to decimals after hitting the first million. And every step is shown on the UI fast.
Do you guys have a solution to achieve this increment effect?
EDIT:
I'd even be happy with an existing Library (if any) to achieve this incrementing effect
This way you'll never see the update because every operation you do on Main Thread (or Looper in android world). You should try something like this:
private final static long MAX_VALUE = 1000000L;
private final static int TIME = 100L;
private final Handler handler = new Handler();
private long value = 1;
private void scheduleIncrementation() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (value < MAX_VALUE) {
textView.setText(String.valueOf(value++));
}
handler.postDelayed(this, TIME);
}
}, TIME);
}
And in onCreate method just call:
scheduleIncrementation();

Button To Flash

Hi im trying to get a button to flash, I have tried to change the background with a loop, but not having much luck any suggestions thanks
int count = 0;
while (count < 10000) { // test: boolean test within (..)
if (count % 2 != 0) {
helpt.setBackgroundColor(getResources().getColor(R.color.Blue));
}
else {
helpt.setBackgroundColor(getResources().getColor(R.color.Red));
}
count = count + 1;
}
This will change the colour every one second:
int count = 0; //Declare as instance variable
Activity activity; //Declare as instance variable
//Inside onCreate()
activity = this;
new Timer().schedule(new TimerTask() {
#Override
public void run() {
activity.runOnUiThread(new Runnable() {
public void run() {
if (count < 10000) {
if (count % 2 != 0) {
helpt.setBackgroundColor(getResources()
.getColor(android.R.color.black));
} else {
helpt.setBackgroundColor(getResources()
.getColor(android.R.color.white));
}
count = count + 1;
}
}
});
}
}, 0, 1000);
You dont have any form of delay, of course you wouldn't see it flash. It will run through that loop very quickly. Also for standards you should be using a for loop, not a while. For is explicityly for when you know how many times you are going to run.

How to create a count-up effect for a textView in Android

I am working on an app that counts the number of questions marks in a few paragraphs of text.
After the scanning is done (which takes no time at all) I would love to have the total presented after the number goes from 0 to TOTAL. So, for 10: 0,1,2,3,4,5,6,7,8,9 10 and then STOP.
I have tried a couple of different techniques:
TextView sentScore = (TextView) findViewById(R.id.sentScore);
long freezeTime = SystemClock.uptimeMillis();
for (int i = 0; i < sent; i++) {
if ((SystemClock.uptimeMillis() - freezeTime) > 500) {
sentScore.setText(sent.toString());
}
}
Also I tried this:
for (int i = 0; i < sent; i++) {
// try {
Thread.sleep(500);
} catch (InterruptedException ie) {
sentScore.setText(i.toString());
}
}
I am sure these are both completely amateur attempts. Any help would be much-appreciated.
Thanks,
Richard
I've used a more conventional Android-style animation for this:
ValueAnimator animator = new ValueAnimator();
animator.setObjectValues(0, count);
animator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
view.setText(String.valueOf(animation.getAnimatedValue()));
}
});
animator.setEvaluator(new TypeEvaluator<Integer>() {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
return Math.round(startValue + (endValue - startValue) * fraction);
}
});
animator.setDuration(1000);
animator.start();
You can play with the 0 and count values to make the counter go from any number to any number, and play with the 1000 to set the duration of the entire animation.
Note that this supports Android API level 11 and above, but you can use the awesome nineoldandroids project to make it backward compatible easily.
Try this:
private int counter = 0;
private int total = 30; // the total number
//...
//when you want to start the counting start the thread bellow.
new Thread(new Runnable() {
public void run() {
while (counter < total) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.post(new Runnable() {
public void run() {
t.setText("" + counter);
}
});
counter++;
}
}
}).start();
The question is very old, but I am posting this so that it would help someone else.
I have used these 2 amazing libraries.
Try them
https://github.com/MasayukiSuda/CountAnimationTextView
Or
2. https://github.com/robinhood/ticker
Hope this helps :) Happy Coding!!!
Use TextSitcher
for the best effects. It will transform the text softly.
When coming to the change of the text use the below Code.
> int number = 0;
> Timer obj = new Timer();
> TimerTask tt = new TimerTask() {
> #Override public void run() {
> // TODO Auto-generated method stub
> textView.setText(number++);
> if(number < score)
> obj.schedule(tt, 200); } };
> obj.schedule(tt, 200);
Use a worker thread to do the waiting and update your UI thread.
You could use an AsyncTask, though it might be an overkill for this job. If you use this, In the doInBackground() loop over the number of sleep periods and after every sleep period, update the count in the UIthread.
There you go! Slukain just gave you the working code :P
Maybe try changing the for loop to something like:
int count = 0;
while (count != sent) {
if ((SystemClock.uptimeMillis() - freezeTime) > 500) {
count++;
sentScore.setText("" + count);
freezeTime = SystemClock.uptimeMillis();
}
}

Categories