After I do some change in my database, that involves significant change in my views, I would like to redraw, re-execute onCreate.
How is that possible?
UPDATE: Android SDK 11 added a recreate() method to activities.
I've done that by simply reusing the intent that started the activity. Define an intent starterIntent in your class and assign it in onCreate() using starterIntent = getIntent();. Then when you want to restart the activity, call finish(); startActivity(starterIntent);
It isn't a very elegant solution, but it's a simple way to restart your activity and force it to reload everything.
Call the recreate method of the activity.
Option 1
Call recreate() on your Activity.
However this method causes a flashing black screen to appear during the activity re-creation.
Option 2
finish();
startActivity(getIntent());
No "flashing" black screen here, but you'll see a transition between the old and the new instances with a not-so-pleasant black background. We can do better.
Option 3
To fix this, we can add a call to overridePendingTransition() :
finish();
startActivity(getIntent());
overridePendingTransition(0, 0);
Good bye black screen, but in my case I still see some kind of transition (a fade animation), on a colored background this time. That's because you're finishing the current instance of your activity before the new one is created and becomes fully visible, and the in-between color is the value of the windowBackground theme attribute.
Option 4
startActivity(getIntent());
finish();
Calling finish() after startActivity() will use the default transition between activities, often with a little slide-in animation. But the transition is still visible.
Option 5
startActivity(getIntent());
finish();
overridePendingTransition(0, 0);
To me, this is the best solution because it restarts the activity without any visible transition, like if nothing happened.
It could be useful if, for example, in your app you expose a way to change the display language independently of the system's language. In this case, whenever the user changes your app's language you'll probably want to restart your activity without transition, making the language switch look instantaneous.
Combining some answers here you can use something like the following.
class BaseActivity extends SherlockFragmentActivity
{
// Backwards compatible recreate().
#Override
public void recreate()
{
if (android.os.Build.VERSION.SDK_INT >= 11)
{
super.recreate();
}
else
{
startActivity(getIntent());
finish();
}
}
}
Testing
I tested it a bit, and there are some problems:
If the activity is the lowest one on the stack, calling startActivity(...); finish(); just exist the app and doesn't restart the activity.
super.recreate() doesn't actually act the same way as totally recreating the activity. It is equivalent to rotating the device so if you have any Fragments with setRetainInstance(true) they won't be recreated; merely paused and resumed.
So currently I don't believe there is an acceptable solution.
When I need to restart an activity, I use following code. Though it is not recommended.
Intent intent = getIntent();
finish();
startActivity(intent);
for API before 11 you cannot use recreate(). I solved in this way:
Bundle temp_bundle = new Bundle();
onSaveInstanceState(temp_bundle);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("bundle", temp_bundle);
startActivity(intent);
finish();
and in onCreate..
#Override
public void onCreate(Bundle savedInstanceState) {
if (getIntent().hasExtra("bundle") && savedInstanceState==null){
savedInstanceState = getIntent().getExtras().getBundle("bundle");
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//code
}
After looking for the gingerbread implement for recreate, I'd like to use following codes (for gingerbread):
activity.mMainThread.mAppThread.scheduleRelaunchActivity(activity.mToken, null, null, 0, false, null);
For these codes, it's from the implementation in higher api.
public void recreate() {
if (mParent != null) {
throw new IllegalStateException("Can only be called on top-level activity");
}
if (Looper.myLooper() != mMainThread.getLooper()) {
throw new IllegalStateException("Must be called from main thread");
}
mMainThread.requestRelaunchActivity(mToken, null, null, 0, false, null, false);
}
Api-10 has no requestRelaunchActivity, however, from the diff, i found this:
public final void scheduleRelaunchActivity(IBinder token,
List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
int configChanges, boolean notResumed, Configuration config) {
- ActivityClientRecord r = new ActivityClientRecord();
-
- r.token = token;
- r.pendingResults = pendingResults;
- r.pendingIntents = pendingNewIntents;
- r.startsNotResumed = notResumed;
- r.createdConfig = config;
-
- synchronized (mPackages) {
- mRelaunchingActivities.add(r);
- }
-
- queueOrSendMessage(H.RELAUNCH_ACTIVITY, r, configChanges);
+ requestRelaunchActivity(token, pendingResults, pendingNewIntents,
+ configChanges, notResumed, config, true);
}
So I think I could use scheduleRelaunchActivity instead of requestRelaunchActivity.
And I have written them using reflect:
package me.piebridge.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Build;
import android.os.IBinder;
public class GingerBreadUtil {
private static Field scanField(Class<?> clazz, String... names) {
for (String name : names) {
Field field;
try {
field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
}
try {
field = clazz.getField(name);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
}
}
return null;
}
public static void recreate(Activity activity) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1) {
recreateHC(activity);
} else {
try {
recreateGB(activity);
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private static void recreateHC(Activity activity) {
((Activity) activity).recreate();
}
private static void recreateGB(Activity activity) throws IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Field Activity$mToken = scanField(Activity.class, "mToken");
IBinder mToken = (IBinder) Activity$mToken.get(activity);
Field Activity$mMainThread = scanField(Activity.class, "mMainThread");
Object mMainThread = Activity$mMainThread.get(activity);
Field ActivityThread$mAppThread = scanField(mMainThread.getClass(), "mAppThread");
Object mAppThread = ActivityThread$mAppThread.get(mMainThread);
Method method = mAppThread.getClass().getMethod("scheduleRelaunchActivity",
IBinder.class, List.class, List.class, int.class, boolean.class, Configuration.class);
method.invoke(mAppThread, mToken, null, null, 0, false, null);
}
}
I'm using these codes for the back-porting of xposed framework.
Call the recreate() method from where you want to recreate your activity . This method will destroy current instance of Activity with onDestroy() and then recreate activity with onCreate().
If this is your problem, you should probably implement another way to do the view filling in your Activity. Instead of re running onCreate() you should make it so onCreate() calls your filling method with some argument. When the data changes, the filling method should get called with another argument.
The way I resolved it is by using Fragments. These are backwards compatible until API 4 by using the support library.
You make a "wrapper" layout with a FrameLayout in it.
Example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Then you make a FragmentActivity in wich you can replace the FrameLayout any time you want.
Example:
public class SampleFragmentActivity extends FragmentActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.wrapper);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null)
{
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null)
{
return;
}
updateLayout();
}
}
private void updateLayout()
{
Fragment fragment = new SampleFragment();
fragment.setArguments(getIntent().getExtras());
// replace original fragment by new fragment
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
}
In the Fragment you inflate/replace you can use the onStart and onCreateView like you normaly would use the onCreate of an activity.
Example:
public class SampleFragment extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.yourActualLayout, container, false);
}
#Override
public void onStart()
{
// do something with the components, or not!
TextView text = (TextView) getActivity().findViewById(R.id.text1);
super.onStart();
}
}
Also depending on your situation, you may need getActivity().recreate(); instead of just recreate().
For example, you should use it if you are doing recreate() in the class which has been created inside class of activity.
In case you want to use recreate and target Android versions lower than 11, use ActivityCompat.recreate(...) using the platform support APIs.
I once made a test app that uploads, deletes, and then redownloads the database file using firebase cloud storage.
To display the data in database, the following code was the only solution I found. Neither recreate() nor finish() worked in this case.
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
System.exit(0);
If you want to pass a parameter to onCreate() then you have to create a new intent with adding extra and call StartActivity with it. Here is a simple example which i did using this way.
String eczSabit = sa.getItem(position).getValue();
if(!Util.IsNullOrEmpty(eczSabit)){
sabit = Long.parseLong(eczSabit);
Intent intent = new Intent(eczaneSegmentasyon.this,eczaneSegmentasyon.class);
intent.putExtra("sabit", sabit);
startActivity(intent);
}
i found out the best way to refresh your Fragment when data change
if you have a button "search", you have to initialize your ARRAY list inside the button
mSearchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mList = new ArrayList<Node>();
firebaseSearchQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
Node p = dataSnapshot1.getValue(Node .class);
mList.add(p);
}
YourAdapter = new NodeAdapter(getActivity(), mList);
mRecyclerView.setAdapter(YourAdapter );
}
If you're just looking to re-do your view, I had the exact same issue. In the onResume function try putting this:
mView = new AndroidPinballView(getApplication());
This was also in my onCreate(), so putting this in the onResume worked for me :)
Related
How do I recreate the activity only once after opening the application?
I tried to do this, but it didn't work. Endlessly recreate()
refreshLang() in onCreate
private fun refreshLang() {
PreferenceManager.getDefaultSharedPreferences(this).apply {
val checkRun = getString("FIRSTRUN", "DEFAULT")
if (checkRun == "YES") {
PreferenceManager.getDefaultSharedPreferences(this#MainActivity).edit().putString("FIRSTRUN", "NO").apply()
recreate()
}
}
}
and SharPref.putString("FIRSTRUN", "YES").apply() in onDestroy to make it work again the next time you run it.
Please refer: Activity class
recreate()
It create new instance and initiates fresh activity lifecycle.
So when you call recreate() it will call onCreate() and will go in endless loop.
You have add some condition to avoid this overflow.
Edit:
Use .equals instead of ==
if ("YES".equals(checkRun)) {
PreferenceManager.getDefaultSharedPreferences(this#MainActivity).edit().putString("FIRSTRUN", "NO").apply()
recreate()
}
I suggest you not to use recreate(). It will call onCreate and onDestory().
Refer below code.
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean recreateRequested = true;
Intent currentIntent = getIntent();
if (currentIntent.hasExtra("recreateRequested")){
recreateRequested = currentIntent.getBooleanExtra("recreateRequested", true);
}
if (recreateRequested) {
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("recreateRequested", false);
startActivity(intent);
finish();
}
}
you can't compare two Strings like this in your if condition
checkRun == "YES"
these are two separated instances of String, so they never be equal in the this meaning (== - same object)
use this instead
"YES".equals(checkRun)
equals will compare "content" of compared objects, in String case it will compare text
use onResume Method
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
}
After upgrading my app to
targetSdkVersion 27
com.android.support:support-v4:27.0.2
I am getting the following crash log from live
Caused by: java.lang.IllegalArgumentException:
at android.support.v4.app.Fragment.setTargetFragment (Fragment.java:545)
I look at the source code of support fragment (Not exactly line 545. I'm not sure how I can get the latest source code of support fragment library)
https://android.googlesource.com/platform/frameworks/support/+/cef09fe/v4/java/android/support/v4/app/Fragment.java#598
598 public void setTargetFragment(Fragment fragment, int requestCode) {
599 mTarget = fragment;
560 mTargetRequestCode = requestCode;
561 }
I can't see a reason why java.lang.IllegalArgumentException is thrown. Maybe I'm looking at wrong version of support library source code?
Do you have any idea, why I'm getting java.lang.IllegalArgumentException during android.support.v4.app.Fragment.setTargetFragment
My source code is as follow
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
public class BuyPortfolioFragment extends Fragment {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// If not retained (or first time running), we need to create it.
if (this.statusBarUpdaterFragment == null) {
this.statusBarUpdaterFragment = StatusBarUpdaterFragment.newInstance();
// Tell it who it is working with.
this.statusBarUpdaterFragment.setTargetFragment(this, 0);
fm.beginTransaction().add(statusBarUpdaterFragment, STATUS_BAR_UPDATER_FRAGMENT).commitAllowingStateLoss();
} else {
statusBarUpdaterFragment.setTargetFragment(this, 0);
}
This is my code, which may crash sometimes. You may reproduce, by reducing background process limit to 1.
public class BuyPortfolioFragment extends Fragment {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// If not retained (or first time running), we need to create it.
if (this.statusBarUpdaterFragment == null) {
this.statusBarUpdaterFragment = StatusBarUpdaterFragment.newInstance();
// Tell it who it is working with.
this.statusBarUpdaterFragment.setTargetFragment(this, 0);
fm.beginTransaction().add(statusBarUpdaterFragment, STATUS_BAR_UPDATER_FRAGMENT).commitAllowingStateLoss();
} else {
statusBarUpdaterFragment.setTargetFragment(this, 0);
}
Note, calling setTargetFragment might not be always necessary due to Is calling setTargetFragment on headless fragment no longer necessary during UI fragment re-creation?
However, to play a safe game, I use the following fix.
public class BuyPortfolioFragment extends Fragment {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// If not retained (or first time running), we need to create it.
if (this.statusBarUpdaterFragment == null) {
this.statusBarUpdaterFragment = StatusBarUpdaterFragment.newInstance();
// Tell it who it is working with.
this.statusBarUpdaterFragment.setTargetFragment(this, 0);
fm.beginTransaction().add(statusBarUpdaterFragment, STATUS_BAR_UPDATER_FRAGMENT).commitAllowingStateLoss();
} else {
// Google poses new restriction recently. A fragment need to have same fragment
// manager as StatusBarUpdaterFragment, in order to become its target fragment. It
// is OK not to call setTargetFragment. Although you may get null from
// statusBarUpdaterFragment.getTargetFragment, during onResume,
// statusBarUpdaterFragment.getTargetFragment will magically return correct fragment.
//statusBarUpdaterFragment.setTargetFragment(this, 0);
}
}
#Override
public void onResume() {
super.onResume();
...
// This code block might not be necessary. Just to be safe.
if (statusBarUpdaterFragment != null) {
// Google poses new restriction recently. A fragment need to have same fragment
// manager as StatusBarUpdaterFragment, in order to become its target fragment. It
// is OK not to call setTargetFragment. Although you may get null from
// statusBarUpdaterFragment.getTargetFragment, during onResume,
// statusBarUpdaterFragment.getTargetFragment will magically return correct fragment.
try {
statusBarUpdaterFragment.setTargetFragment(this, 0);
} catch (java.lang.IllegalArgumentException e) {
// Shouldn't happen. Just to be safe.
Log.e(TAG, "", e);
}
}
I am developing a multi level game, where each level is a new activity.
I want to know, if i change the activity like
Intent myIntent = new Intent(getBaseContext(), Level3.class);
startActivity(myIntent);
The memory used for Level 1 and 2 is cleared?
If not, how can I clear everything from previous level activities so the phone uses just the memory just for the current activity ?
You need to call finish() for the activity (or activities) that you no longer want to be active. You can simply call it right after starting the new activity:
Intent myIntent = new Intent(getBaseContext(), Level3.class);
startActivity(myIntent);
finish();
Otherwise, the previous activity will remain on the activity stack.
since you are using an activity/level design, just add a check if your activity is finishing in your onPause method, and null all your references to the current level, that way the GC will know that your level object should be released, and it will release it as soon as possible.
#Override
public void onPause(){
super.onPause();
if (isFinishing()){
levelObject = null;
}
}
I would not recommend you to create Activity for each of your game level. Would be better to create some Controller that will initializate you game levels in one Activity. And of cource it must have some methods to clear memmory from last stage, something like this :
class StageManager
{
public Stage curStage;
public initStage(Stage stage)
{
//init stage here
curStage = stage;
stage.init();
}
public clearStage()
{
//do some clearing staff
curStage .clear();
}
}
abstract class Stage
{
public abstract init();
public abstract clear();
}
abstract class FirstStage extends Stage
{
//....
}
abstract class SecondStage extends Stage
{
//....
}
In Activity :
StageManager stageManager = new StageManager();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.your_view);
stageManager.init(new FirstStage());
}
#Override
public void onClick(View theView)
{
int id = theView.getId();
if (id == R.id.btnNextLevel) {
stageManager.clear();
stageManager.init(new SecondStage());
}
}
Instead of your custom manager, you can use fragmets :
http://developer.android.com/training/basics/fragments/creating.html
http://developer.android.com/training/basics/fragments/fragment-ui.html
In both ways - fragments or yout own manager you will seperate different stages logic to different classes.
Youd don't need to create another Activity to seperate yours 1000+ lines code. Just use one of Stage or Stratagy desing patters.
And if you still want to use Activities just do something like this :
Intent myIntent = new Intent(getBaseContext(), Level3.class);
startActivity(myIntent);
finish();
and in onDestroy() :
#Override
protected void onDestroy()
{
//here you must clear all data that were used in this Stage (Activity) like this :
clearMemmory();
super.onDestroy();
}
private void clearMemmory()
{
if(stageData!=null)
{
stageData.clear();
stageData =null;
}
}
or clear memmory directly before opening another Stage, something like :
clearMemmory();
Intent myIntent = new Intent(getBaseContext(), Level3.class);
startActivity(myIntent);
finish();
Best wishes.
I try to write an instrumentation test that tests the activity lifecycle where my activity gets killed and it's instance state gets saved and then gets recreated with this instance state.
I can test this behavior manually by limiting the background process limit to "no background processes" in the developer settings of my device, but I want to be able to have an automated test that proves that my activity can be recreated.
My activity has a fragment with id R.id.content_frame.
So for I have this:
public class MainActivityInstrumentationTest extends ActivityInstrumentationTestCase2<MainActivity> {
public void testKillCreateLifeCycleWithProfileFragment() throws Throwable {
final Activity activity = getActivity();
navigateToProfile(activity);
Thread.sleep(5000);
runTestOnUiThread(new Runnable() {
#Override
public void run() {
activity.recreate();
}
});
getInstrumentation().waitForIdleSync();
Thread.sleep(5000);
assertProfileFragmentIsVisible((FragmentActivity) activity);
}
private void assertProfileFragmentIsVisible(FragmentActivity activity) {
FragmentManager supportFragmentManager = activity.getSupportFragmentManager();
Fragment currentFragment = supportFragmentManager.findFragmentById(R.id.content_frame);
assertEquals(ProfileFragment.class.getName(), currentFragment.getClass().getName());
}
}
activity.recreate goes through all the live cycle callback methods and ultimalty calls onCreate with the saved bundle but the fragmentManager in my assertProfileFragmentIsVisible method does not contain any fragments.
Also I'm not sure whether to use activity.recreate is a right way to go. I tried many other ways like calling each life cycle method manually with getInstrumentation().callActivityOn...but then ultimately found no way of creating the activity with the saved bundle..
Any ideas on how I can create such an instrumentation test would be appreciated!
Regards
Frank
Just in case anybody is interested in my final solution:
The problem was that I put the reference to the old activity to assertProfileFragmentIsVisible. But activity.recreate() creates a new activity instance.
The problem remains how to get this reference.
I managed to obtain a reference to the new activity by using the ActivityMonitor.
So my complete test now looks as follows:
public void testKillCreateLifeCycle() throws Throwable {
Instrumentation.ActivityMonitor mainActivityMonitor = new Instrumentation.ActivityMonitor(MainActivity.class.getName(), null, false);
getInstrumentation().addMonitor(mainActivityMonitor);
final Activity activity = getActivity();
mainActivityMonitor.waitForActivityWithTimeout(5000);
navigateToFragment(activity);
runTestOnUiThread(new Runnable() {
#Override
public void run() {
activity.recreate();
}
});
getInstrumentation().waitForIdleSync();
Activity newActivity = mainActivityMonitor.getLastActivity();
assertFragmentIsVisible((FragmentActivity) newActivity, getExpectedFragment());
}
I have a View that was created on runtime then I draw some canvas on that View(runtime) after that I rotated my screen.All data was gone(reset).So I put the some code in AndroidManifest.xml like this
android:configChanges="keyboardHidden|orientation"
in my <activity> then I put a #Override function
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout) findViewById(R.id.myPaint);
layout.addView(mView);
}
but everything couldn't solved my problem.I want to keep my data from View(runtime) on every single rotation.
That's my onCreate function.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mView = new MyView(this);
setContentView(mView);
mView.requestFocus();
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout) findViewById(R.id.myPaint);
layout.addView(mView);
}
You need to save and load the data you want to retain. Even though you're handling the screen rotation yourself when you modified the Manifest the way you did, you're still reloading the view yourself. Reread the reference document on Handling Runtime Changes. You need to store your data and reload it accordingly. Otherwise it will be lost when the application restarts or when you reload your ContentView.
http://developer.android.com/guide/topics/resources/runtime-changes.html
You could approach this a few ways.
I assume MyView is your own class which extends View. If so there are two methods which you may care to know, onSaveInstanceState() and onRestoreInstanceState(). When saving you create a parcelable that will contain enough data for you to re-render your view if it were to be destroyed and recreated.
class MyView extends View {
private String mString;
onDraw(Canvas v) { ... }
Parcelable onSaveInstanceState() {
Bundle b = new Bundle();
bundle.putString("STRING", mString);
return b;
void onRestoreInstanceState(Parcelable c) {
Bundle b = (Bundle) c;
mString = bundle.getString("STRING", null);
}
}
Activity has similar state saving mechanics allowed in onCreate and onSaveInstanceState() (inside Activity, not View in this case) which will allow the activity to reset the state of it's view to the state it desires.
This should solve most of your worries. If you are wanting to use the onConfigurationChanged method, then you should reclarify your question as it is not clear what the current behavior is that you aren't expecting in each situation (only using onConfigurationChanged, or only using onCreate, or using both, etc).
I've just used my data-class as singleton (java-pattern).
And it works fine.
--> Application is a Stop-Timer for Racing, where i can stop time from different opponents on the track, so i need the data for longer time, also if the view is repainted.
regz
public class Drivers {
// this is my singleton data-class for timing
private static Drivers instance = null;
public static Drivers getInstance() {
if (instance == null) {
instance = new Drivers();
}
return instance;
}
// some Timer-Definitions.......
}
Then in MainActivity:
// now the class is static, and will alive during application is running
private Drivers drivers = Drivers.getInstance();
#Override
public void onClick(View v) {
if (v == runButton1) {
drivers.startTimer1();
// do some other crazy stuff ...
}
}
// here i put out the current timing every second
private myUpdateFunction(){
time01.setText(drivers.getTimer1());
// update other timers etc ...
}