Extended class calling function that should not be inherited - android

i have following problem:
I've made a simple android app that adds 1 to an integer every 1000 ms using a handler, and then display this integer.
The problem is that when i start another activity the same thing happens, which would be fine, if that was intended. The mentioned function is not called in the new activity and yet it seems to be. Please look over my code and show me where it went wrong..
MainActivity:
public class MainActivity extends ActionBarActivity {
protected TextView text;
protected int position;
private Handler handler = new Handler();
private int i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
position=0;
SetButtonCLickListener();
counter();
}
protected void SetButtonCLickListener() {
Button btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SwitchActivity();
}
});
}
private void counter() {
handler.removeCallbacks(count);
handler.postDelayed(count, 1000);
}
private Runnable count = new Runnable() {
public void run() {
i++;
text.setText("Count: " + i);
handler.postDelayed(count, 1000);
}
};
protected void SwitchActivity() {
if (position == 1) {
finish();
} else {
Intent intent = new Intent(this, MainActivity2.class);
startActivity(intent);
}
}
}
SecondActivity
public class MainActivity2 extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity2);
text = (TextView) findViewById(R.id.text);
SetButtonCLickListener();
position=1;
}
}

MainActivity2 has an onCreate() method. In the onCreate() method, you call super.onCreate(), which triggers the MainActivity implementation of onCreate(). The MainActivity implementation of onCreate() is where you are starting your counter thing, via its call to the counter() method. Hence, when MainActivity2 starts up, its onCreate() calls MainActivity's onCreate(), which calls counter().
My guess is that MainActivity2 should inherit from Activity, not from MainActivity.

Related

How to start a countdown with a textview from another class?

I am making a countdown timer in android eclipse and I want to use a Textview from another class.
This is my first class
public class Main extends Activity {
Spinner timerValueSpinner;
Button startButton;
TextView statusTextView;
Countdown timer;
String[] timeValues;
Resources resourcePointer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerValueSpinner = (Spinner)this.findViewById(R.id.secondsSpinner);
statusTextView = (TextView)this.findViewById(R.id.timerView);
resourcePointer = getResources();
timeValues = resourcePointer.getStringArray(R.array.seconds_list);
startButton = (Button)this.findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Main.this,Timer.class);
startActivity(intent);
if(timerValueSpinner.getSelectedItemPosition() > -1){
int parsedSpinnerValue = 0;
parsedSpinnerValue = Integer.parseInt(timeValues[timerValueSpinner.getSelectedItemPosition()]);
if(parsedSpinnerValue > 0){
if(timer != null){
timer.cancel();
}
timer = new Countdown(parsedSpinnerValue
* Countdown.oneSecond, Countdown.oneSecond,statusTextView);
timer.start();
}
}
}
});
}
This is my Second class and I want to get its statusTextVie and use it in the First(Main) class instead of its own textview so when I click the button the second class will show and the countdown will start from its textview.
public class Timer extends Activity {
TextView statusTextVie;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
statusTextVie = (TextView)this.findViewById(R.id.timerVie);
}
This is my first time asking a question here, so I am sorry if i made some mistakes.
Why not pass the time value from the first activity to second activity via intent and start the thread in second activity ?
First Activity:
public class Main extends Activity {
Spinner timerValueSpinner;
Button startButton;
String[] timeValues;
Resources resourcePointer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerValueSpinner = (Spinner)this.findViewById(R.id.secondsSpinner);
resourcePointer = getResources();
timeValues = resourcePointer.getStringArray(R.array.seconds_list);
startButton = (Button)this.findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Main.this,Timer.class);
if(timerValueSpinner.getSelectedItemPosition() > -1){
int parsedSpinnerValue = 0;
parsedSpinnerValue = Integer.parseInt(timeValues[timerValueSpinner.getSelectedItemPosition()]);
if(parsedSpinnerValue > 0){
intent.putExtra("TimeValue", parsedSpinnerValue);
startActivity(intent);
}
}
}
});
}
Second Activity:
public class Timer extends Activity {
Countdown timer;
TextView statusTextVie;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
Bundle extras = getIntent().getExtras();
int timeVal = extras.getInt("TimeValue", 0);
statusTextVie = (TextView)this.findViewById(R.id.timerVie);
if (timeVal > 0){
if(timer != null){
timer.cancel();
}
timer = new Countdown(timeVal * Countdown.oneSecond, Countdown.oneSecond,statusTextVie);
timer.start();
}
}
}

Counter in loop

How to do sample counter in Activity? This is not working.
public class MainActivity extends AppCompatActivity implements Runnable {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
run();
}
#Override
public void run() {
while (true) {
updateTv();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void updateTv() {
int counter = 100;
final TextView tv = (TextView) findViewById(R.id.tv);
tv.setText(String.valueOf(counter));
counter--;
}
}
In onCreate() you're starting an infinite loop inside of the UI thread, blocking it completely. Alternatively you could use a Handler for periodic updates. Maybe using a bigger delay and stop it sometime.
public class MainActivity extends AppCompatActivity implements Runnable {
private final Handler mHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
run();
}
#Override
public void run() {
updateTv();
mHandler.postDelayed(this, 17);
}
public void updateTv() {
int counter = 100;
final TextView tv = (TextView) findViewById(R.id.tv);
tv.setText(String.valueOf(counter));
counter--;
}
}
Anyway you should read What is the Android UiThread (UI thread) for sure.
Consider using Timer class which allows you to define a callback method that will be invoked at specified rate.
An example that fits your needs:
public class CounterActivity extends AppCompatActivity {
private TextView mCounterTextView;
private Timer mTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_counter);
mCounterTextView = (TextView) findViewById(R.id.counterTextView);
mTimer = new Timer();
mTimer.scheduleAtFixedRate(
new CounterTask(100), 0, TimeUnit.SECONDS.toMillis(1));
}
protected class CounterTask extends TimerTask {
protected int mCounter;
CounterTask(int initial) {
mCounter = initial;
}
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
mCounterTextView.setText(String.valueOf(mCounter));
}
});
--mCounter;
}
}
}
One more thing that should be noticed. As Timer executes it's own thread - it prevents you from updating your UI from outside of the main thread. In that case
you have to register a Runnable using runOnUiThread method.
Also, calling findViewById in a loop is not the best idea.

Interface method cannot change TextView text in android

I am running an android service. I wish to change a TextView text when I get expected result from the service. I have implemented an interface method to get a callback to change my textView. Interface abstract method runs well but cannot change the Textview text of my activity.
I have simplified sample code here
public class MainActivity extends Activity implements MyInterface {
TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.sample_text);
Button btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("Asim----", "Start service"); // print this line well
startService(new Intent(MainActivity.this, MyService.class));
}
});
}
#Override
public void testMe() {
Log.e("Asim----", "Hi"); // print this line well
mTextView.setText("New Text"); // Chrashes happens here
}
}
The MyService class here
public class MyService extends Service {
#Override
public void onCreate() {
//super.onCreate();
Log.e("test1------", "onCreate"); // print this line well
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("test2------", "onStartCommand"); // print this line well
MyInterface mi = new MainActivity();
mi.testMe();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
mTextView should be null you have to find it in this method
#Override
public void testMe() {
Log.e("Asim----", "Hi"); // print this line well
mTextView = (TextView) findViewById(R.id.sample_text);
mTextView.setText("New Text"); // Chrashes happens here
}
Try it once.
you need to pass Activity in your interface as well
#Override
public void testMe(Activity actvity) {
Log.e("Asim----", "Hi"); // print this line well
mTextView = (TextView) activity.findViewById(R.id.sample_text);
mTextView.setText("New Text"); // Chrashes happens here
}

How to use other task while AsyncTask?

I'm practicing on async tasks. I want to use intent while the program is performing some calculation.
I can't use the intent in onClick, probably in onProgressUpdate.
public class MainActivity extends Activity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStart=(Button) findViewById(R.id.btnStart);
Button btnAsync=(Button) findViewById(R.id.btnAsync);
btnStart.setOnClickListener(this);
btnAsync.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart:
doLongTaskOnMain(50001);
break;
case R.id.btnAsync:
LongTask task=new LongTask();
task.execute(50000);
break;
}
}
private void doLongTaskOnMain(int number){
TextView textOutput=(TextView) findViewById(R.id.textOutput);
textOutput.setText("Calculating sum of :"+number);
long sum=0;
for(int i=0;i<number; i++){
sum+= i;
textOutput.setText("Progress"+100f*i/number);
}
textOutput.setText("Sum: "+sum);
}
class LongTask extends AsyncTask<Integer, Float, Long>{ //<Params, Progress, Result>
#Override
protected void onPreExecute() {
TextView textOutput=(TextView) findViewById(R.id.textOutput);
textOutput.setText("Start");
}
#Override
protected Long doInBackground(Integer... params) {
int number= params[0];
long sum=0;
for(int i=0;i<number;i++){
sum+=i;
publishProgress(100f*i/number);
}
return sum;
}
#Override
protected void onProgressUpdate(Float... values) {
Float progress=values[0];
TextView textOutput=(TextView) findViewById(R.id.textOutput);
textOutput.setText("progress "+Math.round(progress)+"%");
Button btnNext=(Button) findViewById(R.id.btnNext);
}
#Override
protected void onPostExecute(Long result) {
TextView textOutput=(TextView) findViewById(R.id.textOutput);
textOutput.setText("sum: "+result);
}
}
}
The Second Activity:
public class SecondActivity extends Activity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Button btnBack= (Button) findViewById(R.id.btnBack);
btnBack.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
Intent intent=new Intent(this,MainActivity.class);
startActivity(intent);
}
}
How can I move to the second activity without stopping the calculation?
You can make your AsyncTask a standalone class, and have it an Activity member (better a weak reference though). Then, in your first activity's onCreate() you set that member to the first Activity, in a second Activity's onCreate() to the 2nd activity.
This way your onPostExecute will have the correct activity.
You can probably use an event bus instead such as Green Robot

How can i code a time limit in my android game

i have a quiz game for my android that has a time limit. what i want is there is a choices button that if you click one of the buttons it you will be automatically intent to the class next level but if you didnt answer or click any of the button you will be intent to the other class, thats why the game has a time limit. my problem is i dont know how to put a time limit that will intent or transfer you in another class automatically if you didnt click any of the button choices. i tried sleep but what happen is even i already clicked the correct answer and im on the next level class it will sleep to the class i intented to my sleep. please help me with my problem. i also try handler but didnt work
public class EasyOne extends Activity {
Button a, b, c;
TextView timer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.easyone);
a = (Button) findViewById(R.id.btn_ea1);
b = (Button) findViewById(R.id.btn_eb1);
c = (Button) findViewById(R.id.btn_ec1);
a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"CORRECT!",
Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(),EasyTwo.class);
startActivity(intent);
}
});
}
private Runnable task = new Runnable() {
public void run() {
Handler handler = new Handler();
handler.postDelayed(task, 5000);
Intent intent = new Intent(getApplicationContext(),TimesUp.class);
startActivity(intent);
}
};
You should use a handler but in order to cancel the timeout you must remove the delayed message from the handler in your click listener code.
public class EasyOne extends Activity {
static private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 123) {
((EasyOne) msg.obj).onTimeout();
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.easyone);
a = (Button) findViewById(R.id.btn_ea1);
b = (Button) findViewById(R.id.btn_eb1);
c = (Button) findViewById(R.id.btn_ec1);
Message msg = mHandler.obtainMessage(123,this);
mHandler.sendMessageDelayed(msg,5000);
a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"CORRECT!",
Toast.LENGTH_SHORT).show();
mHandler.removeMessages(123,this);
Intent intent = new Intent(getApplicationContext(),EasyTwo.class);
startActivity(intent);
}
});
}
private void onTimeout() {
//your code
}
}

Categories

Resources