I have two activities(MainActivity,Sample) which extend to a custom activity(BaseActivity) i have created. I have created a handler which runs a runnable every 5 seconds in BaseActivity. In BaseActivity i have overridden onpause and onresume methods to start and stop handler whenever needed. When i remove the callbacks of handler in onPause of BaseActivity, the handler stops but won't stop in onpause of MainActivity. Below is the code.
public class BaseActivity extends Activity{
public int mInterval = 5000;
public Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("Oncreate baseactivity");
mHandler = new Handler();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
Log.d("MyApp", "every 5 secs");
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
#Override
protected void onPause() {
super.onPause();
System.out.println("OnPause baseactivity");
//stopRepeatingTask();
}
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
#Override
protected void onResume() {
super.onResume();
System.out.println("Onresume baseactivity");
startRepeatingTask();
}
}
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void newpage(View v){
startActivity(new Intent(this,Sample.class));
}
#Override
protected void onPause() {
super.onPause();
System.out.println("onpause mainactivity");
stopRepeatingTask();
}
}
public class Sample extends BaseActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.txt);
tv.setText("sample activity");
}
}
The Onpause of both BaseActivity and mainActivity are called but the handler still runs if the app is closed. I hope am clear.
I think to start thread we should use start() method,
and write onPause method of MainActivity in BaseActivity Itself and remove in MainActivity(i mean stopRepeating Task).
I hope it works.
Related
In my application i want to sign out to loginActivity after 3 min when user inactive
i am currently use this code to do that but in my application there is more than 20 activities
so without pasting this bunch of code every activity i want common method to do that,
please help me
Here is the my code
public class HomeActivity extends AppCompatActivity {
private Handler handler;
private Runnable r;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
handler = new Handler();
r = new Runnable() {
#Override
public void run() {
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(intent);
finish();
Toast.makeText(HomeActivity.this, "Logged out after 3 minutes on inactivity.", Toast.LENGTH_SHORT).show();
}
};
startHandler();
}
public void stopHandler() {
handler.removeCallbacks(r);
}
public void startHandler() {
handler.postDelayed(r, 3 * 60 * 1000);
}
#Override
public void onUserInteraction() {
super.onUserInteraction();
stopHandler();
startHandler();
}
#Override
protected void onPause() {
stopHandler();
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
startHandler();
Log.d("onResume", "onResume_restartActivity");
}
#Override
protected void onDestroy() {
super.onDestroy();
stopHandler();
}
}
Define a class like
public class BaseActivity extends AppCompatActivity {
// Write logic of logout same as what you wrote in HomeActivity
}
Now extend this BaseActivity to each activities which meant to show after login. like
public class HomeActivity extends BaseActivity {
// Remove code related to logout from this class.
}
You can make a BaseActivity Class here you can implement your functionality.
And then extend this activity with all your Activities.
Also you can use Application Class to control over the app
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.
I am working in a Hello Otto basic project in order to learn a bit how it works. This is my BusProvider over Otto 7.0.1. In MainActivity I have two buttons, after tap on the first one I post a string in the bus object. This is my BusProvider
public class BusProvider {
private BusProvider() {}
private static Bus bus;
public static Bus getInstance() {
if (bus == null){
bus = new Bus();
}
return bus;
}
}
MainActivity who will sent a String to Main2Activity using the bus class
public class MainActivity extends AppCompatActivity {
private Bus bus;
#Bind(R.id.myButton)Button mButton;
#Bind(R.id.button2)Button mButton2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setLibreries();
this.bus = BusProvider.getInstance();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
public void setLibreries(){
ButterKnife.bind(this);
}
#OnClick(R.id.myButton)
protected void buttonPressed1( ){
Toast.makeText(this, "click on the 1 button",Toast.LENGTH_SHORT).show();
BusProvider.getInstance().post("HELLO OTTO");
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
}
#OnClick(R.id.button2)
protected void buttonPressed(){
Toast.makeText(this, "click on the 2 button",Toast.LENGTH_SHORT).show();
}
}
Main2Activity how receives the String
public class Main2Activity extends AppCompatActivity {
private Bus bus;
#Bind(R.id.this_is_a_text_view) TextView myTextButter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
bus = BusProvider.getInstance();
ButterKnife.bind(this);
myTextButter.setText("HELLO");
}
#Override
protected void onResume() {
BusProvider.getInstance().register(this);
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
#Subscribe
public void gettingStringPosted(String message){
Log.d("OTTO", "OTTO subscribe has been called "+message);
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
}
The problem is that the Toast with the message I am sending in MainActivity to Main2Activity
HELLO OTTO
is never showed.
What I am doing wrong?
The problem is that your Main2Activity has not been registered yet to Otto when your BusProvider.getInstance().post("HELLO OTTO"); line comes.
Here is how your code does:
Bus.post()
Bus.register()
This is how it should go:
Bus.register()
Bus.post()
You can't solve this by moving the line BusProvider.getInstance().post("HELLO OTTO"); under the startActivity() call because Activity.onResume() might not get called straight away so your register call (in onResume) could still happen after post call. I hope this makes sense to you.
This is just example of otto, to make sense how it is. Let's assume you have a service, and in it getting locations and sending to activities.
public class TrackingService extends Service {
Bus bus;
LocationListener mListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
bus.post(new MyLocation(location));
}
};
// Other service related methods..
}
And activity
#Override
protected void onResume() {
BusProvider.getInstance().register(this);
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
#Subscribe
public void locationChanged(MyLocation location){
Toast.makeText(this, "you got new location", Toast.LENGTH_SHORT).show();
}
Thats just it.
BTW, and this is the what i mentioned for you in my comment
In MainActivity
Intent intent = new Intent(getBaseContext(), Main2Activity.class);
intent.putExtra("MY_INFO", "INFO");
startActivity(intent)
In Main2Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view);
Intent intent = getIntent();
String info = intent.getStringExtra("MY_INFO");
}
I created two Activities "SplashActivity and AuthenticationActivity" When I start the app it loads the splash screen for 5 seconds and then it moves on to AuthenticationActivity. My problem is that when I run the app, it loads the splash screen, but within 5 seconds when I click the back button, SplashActivity exits, and immediately AuthenticationActivity appears in the foreground.
Does anyone know how to make it so when I click the back button, my app exits?
Here's my code so far:
public class SplashActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Thread splashTimer = new Thread(){
public void run(){
try{
sleep(5000);
startActivity(new Intent(SplashActivity.this,AuthenticationActivity.class));
finish();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
finish();
}
}
};
splashTimer.start();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}}
Timer timer;
TimerTask timerTask;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
initialize();
}
private void initialize()
{
timer = new Timer();
timerTask = new TimerTask()
{
#Override
public void run()
{
//Start your activity here
}
};
timer.schedule(timerTask,2500);
}
#Override
public void onBackPressed() {
super.onBackPressed();
timer.cancel();
}
or you can use Handler also
Handler handler;
Runnable runnable;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
initialize();
}
private void initialize()
{
handler = new Handler();
runnable = new Runnable()
{
#Override
public void run()
{
//start your activity here
}
};
handler.postDelayed(runnable, 5000);
}
#Override
public void onBackPressed() {
super.onBackPressed();
handler.removeCallbacks(runnable);
}
I want to reload my activity after every 1 minute. I tried using handler for this... but problem is that when i press back key of device, it doesn't stop and goes into an infinite loop..
here is my code what i have done--
public class Chat extends Activity {
Handler handler;
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.chat);
handler = new Handler();
Toast.makeText(getApplicationContext(), "again", 400).show();
doTheAutoRefresh();
}
private void doTheAutoRefresh() {
handler.postDelayed(new Runnable() {
public void run() {
Intent intent = getIntent();
startActivity(intent);
finish();
//doTheAutoRefresh();
}
}, 10000);
}
public void onPause() {
super.onPause();
}
}
You should do this to remove all handler's messages and callbacks:
public void onPause() {
super.onPause();
handler.removeCallbacksAndMessages(null);
}