Method stops running after switching activities - android

In this app the users score is supposed to increase every second or so, and they can use that score and buy upgrades from the second Activity. When the user starts the app the program works fine, but when they go from the first activity to the second and back it stops updating the textview with the score that increases every second. Can you guys explain whats going on?
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int add = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
if (bundle.containsKey("Count")) {
Counter = bundle.getInt("Count");
}
if (bundle.containsKey("Add")) {
add = bundle.getInt("Add");
}
}
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Counter = ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
}
});
handler.postDelayed(new Runnable() {
#Override
public void run() {
Counter= AutoCounter(Counter, add);
Display(Counter);
handler.postDelayed(this, 1000);
}
},100);
}
public int ButtonCounter(int Counter) {
Counter += 1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter += add;
return Counter;
}
public void Display(int Counter) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
}

You start the counting handler only inside onCreate() method.
When you go back from SecondActivity to MainActivity the onResume() method is called, So
You need to start the counting inside onResume() method.
P.S Make sure to check for nulls before updating you UI from postDelay().
Your Activity might be destroyed by the time the code runs, make sure your TextView is not null before updating.

Related

How to solve "Error: Only the original thread that created a view hierarchy can touch its views." Any suggestions?

Based on an earlier question. My button changes the value of the variable clicks. I was having trouble having visibletotals show at all times and be updated accurately. It was remaining static and stuck at 0. Example below of what my original code was doing. Only the value in the on click method was updating and it only showed upon click.
visibletotals.setText("Evolutions Points: " + clicks);
I moved this line into my timer. I believe the visibletotals TextView is now updating correctly. However, it completely crashed my app giving me this error: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
How do I solve this error while keeping the TextView in my timer?
full code:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
TextView points;
TextView visibletotals;
Button click;
Button upgradebtn;
TextView Leveltext;
int clicks = 0;
int clickcost = 10;
int upgradelevel = 1;
Timer myTimer = new Timer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
click = (Button) findViewById(R.id.click);
points = (TextView) findViewById(R.id.points);
upgradebtn = (Button) findViewById(R.id.upgradebtn);
Leveltext = (TextView) findViewById(R.id.leveltext);
visibletotals = (TextView) findViewById(R.id.visibletotals);
click.setEnabled(true);
upgradebtn.setEnabled(true);
myTimer.schedule(new TimerTask() {
#Override
public void run() {
clicks+= upgradelevel;
visibletotals.setText("Evolutions Points: " + clicks);
}
}, 0, 1000);
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
clicks++;
points.setText(getResources().getString(R.string.evol) + clicks);
}
});
upgradebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (clicks >= clickcost) {
clicks -= clickcost;
upgradelevel += 1;
clickcost *= 2;
upgradebtn.setText(getResources().getString(R.string.Upgrade) +
clickcost +
getString(R.string.LevelText)
+ upgradelevel);
};
}
});
}
}

Making a line of code repeat in android every second

This is the line i want to repeat.
handler.postDelayed(runnableCode, 1);
This app is a tycoon app and so the user can buy upgrades and if they tap the button the get $$ and so when they buy upgrades keeping the value up-to-date is required.
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter = 0;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int Test = 5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler.postDelayed(runnableCode, 1);
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
finish();
}
});
}
public int ButtonCounter(int Counter){
Counter+=1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter+=add;
return Counter;
}
public void Display(int Counter, TextView myTextView) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
private Runnable runnableCode = new Runnable() {
#Override
public void run() {
// Do something here on the main thread
Counter = AutoCounter(Counter,Test);
Display(Counter, myTextView);
}
};
}
handler.postDelayed(runnableCode, 1);
call that line inside onResume() method. Make sure your show an AlertDialog to the user whenever he or she hits the button to get $$. Since the AlertDialog pops up everytime the user tries to buy $$. onResume() will be called.
Try this
private void startAnimation() {
countDownTimer = new CountDownTimer(700, 500) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
//your code to repeat
}
start();
}
}.start();
}

onSaveInstanceState not working as expected

I have a button that goes from one activity to another activity and its supposed to save the value int Counter, but every time it never saves. What am I doing wrong? I have seen other solutions, but i check and im doing the exact same thing as them.
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int add;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
add = savedInstanceState.getInt("Count");
Counter = savedInstanceState.getInt("Add");
}
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Counter = ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
}
});
handler.postDelayed(new Runnable() {
#Override
public void run() {
Counter = AutoCounter(Counter, add);
Display(Counter, myTextView);
handler.postDelayed(this, 100);
}
}, 10);
}
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("Count", Counter);
savedInstanceState.putInt("Add", add);
}
public int ButtonCounter(int Counter) {
Counter += 1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter += add;
return Counter;
}
public void Display(int Counter, TextView myTextView) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
}
you're not implementing the right method
from the docs:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("Count", Counter);
savedInstanceState.putInt("Add", add);
// call superclass to save any view hierarchy
super.onSaveInstanceState(outState);
}
Source: https://developer.android.com/guide/components/activities/activity-lifecycle.html#oncreate

onsaveInstancestate not saving int values

When i try rotating the screen it does not erase the data, but when I go from the activity and back the counter value goes back to 0.
I have set make the method for saving the data, but it still doesnt save. Why is this?
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter = 0;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int add = 0;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
Counter = savedInstanceState.getInt("Count");
add = savedInstanceState.getInt("Add");
}
setContentView(R.layout.activity_main);
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Counter = ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
finish();
}
});
handler.postDelayed(new Runnable() {
#Override
public void run() {
Counter = AutoCounter(Counter, add);
Display(Counter, myTextView);
handler.postDelayed(this, 100);
}
}, 10);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("Count", Counter);
savedInstanceState.putInt("Add", add);
super.onSaveInstanceState(savedInstanceState);
}
public int ButtonCounter(int Counter) {
Counter += 1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter += add;
return Counter;
}
public void Display(int Counter, TextView myTextView) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
}
My code runs like that...
#Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putInt("Count", Counter);
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null)
{
if (savedInstanceState.containsKey("Count"))
{
Counter = savedInstanceState.getInt("Count");
}
}
}
Difference is that i don't have final Bundle on create and i save it after super.onSave.. wich seems odd....

TextView Text Not Updating

package com.aviyehuda.test.multithreading;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MultithreadingTest extends Activity {
Button btn;
private Handler myHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.Button01);
}
public void buttonClicked(View v) {
myHandler = new Handler();
MyThread mThread = new MyThread();
mThread.start();
}
class MyThread extends Thread {
#Override
public void run() {
for (int i = 0; i < 30; i++) {
myHandler.post(new NewThreaad(i));
}
}
}
class NewThreaad implements Runnable{
int i;
public NewThreaad(int n) {
i=n;
}
#Override
public void run() {
((TextView) findViewById(R.id.TextView01)).setText("Hello:"+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I have code mentioned above but getting result Hello29 on TextView but i want Hello1,Hello2,hello3.................Hello29 one by one automatically
Please give me hint what I am doing wrong
A couple of things.
First, after changing the text, you should call invalidate on the TextView to force a refresh.
Second, to do operation on the UI, you should run that in the UI thread. Use runOnUiThread
Well, the main problem is that you're not appending you are overwriting. Instead of
((TextView) findViewById(R.id.TextView01)).setText("Hello:"+i);
do
TextView tv = ((TextView) findViewById(R.id.TextView01));
String text = tv.getText().toString();
tv.setText(text + " Hello:" + i);
You need to move the 500 ms delay to your for-loop, between posting of messages. I think you're expecting the messages to execute sequentially one after the other, but they don't, which is the reason you just see the result of the last one.

Categories

Resources