How can I execute something just once per application start?

前端 未结 10 1355
感情败类
感情败类 2020-11-28 06:45

I\'d like to implement an update checker in an application, and I obviously only need this to show up once when you start the application. If I do the call in the onCr

相关标签:
10条回答
  • 2020-11-28 07:20
          try {
    
              boolean firstboot = getSharedPreferences("BOOT_PREF",MODE_PRIVATE)
        .getBoolean("firstboot", true);
    
                        if(firstboot){
                    //place your code that will run single time                  
    getSharedPreferences("BOOT_PREF",MODE_PRIVATE).edit().
        putBoolean("firstboot", false)
                            .commit();
    
    
                        }
    
    0 讨论(0)
  • 2020-11-28 07:22

    Yes you can do it Using SharedPrefernce concept of android. Just create a boolean flag and save it in SharedPrefernce and check its value in your onCreate() method .

    0 讨论(0)
  • 2020-11-28 07:27

    The shared preferences approach is messy, and the application class has no access to an activity.

    Another alternative I've used is to have a retained fragment instance, and within that instance, a lot more stuff can be done especially if you need access to the main activity UI.

    For this example, I've used asynctask within the retained fragment. My AsyncTask has callbacks to the parent activity. It is guaranteed to run only once per application because the fragment is never destroyed-recreated when the same activity is destroyed-recreated. It is a retained fragment.

    public class StartupTaskFragment extends Fragment {
    
    public interface Callbacks {
        void onPreExecute();
        void onProgressUpdate(int percent);
        void onCancelled();
        void onPostExecute();
    }
    
    public static final String TAG = "startup_task_fragment";
    private Callbacks mCallbacks;
    private StartupTask mTask;
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mCallbacks = (Callbacks) activity;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        setRetainInstance(true); // this keeps fragment in memory even if parent activity is destroyed
    
        mTask = new StartupTask();
        mTask.execute();
    }
    
    @Override
    public void onDetach() {
        super.onDetach();
        mCallbacks = null;
    }
    
    private class StartupTask extends AsyncTask<Void, Integer, Void> {
    
        @Override
        protected void onPreExecute() {
            if (mCallbacks != null) {
                mCallbacks.onPreExecute();
            }
        }
    
        @Override
        protected Void doInBackground(Void... ignore) {
    
            // do stuff here
    
            return null;
        }
    
        @Override
        protected void onProgressUpdate(Integer... percent) {
            if (mCallbacks != null) {
                mCallbacks.onProgressUpdate(percent[0]);
            }
        }
    
        @Override
        protected void onCancelled() {
            if (mCallbacks != null) {
                mCallbacks.onCancelled();
            }
        }
    
        @Override
        protected void onPostExecute(Void ignore) {
            if (mCallbacks != null) {
                mCallbacks.onPostExecute();
            }
        }
    }
    }
    

    Then, in main (or parent) activity where you want this startup task fragment to run once.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        FragmentManager fm = getFragmentManager();
        StartupTaskFragment st = (StartupTaskFragment) fm.findFragmentByTag(StartupTaskFragment.TAG);
    
        if(st == null) {
            fm.beginTransaction().add(mStartupTaskFragment = new StartupTaskFragment(), StartupTaskFragment.TAG).commit();
        }
    
        ...
    }
    

    Ideas for retained fragment came from here: http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html. I just figured out its other uses aside from config changes.

    0 讨论(0)
  • 2020-11-28 07:30

    I just solved doing this myself, I reopen my main activity multiple times throughout the application's execution. While the constructor is a valid approach for some things it doesn't let you access the current Application context to write toasts among other things.

    My solution was to create a simple 'firstRun' boolean set to true in the class of my MainActivity, from there I run the contents of the if statement then set it to true. Example:

    public class MainActivity extends AppCompatActivity
    {
         private static boolean firstRun = true;
    
         @Override
         protected void onCreate(Bundle savedInstanceState)
         {
             if(firstRun)
             {
                  Toast.makeText(getApplicationContext(), "FIRST RUN", Toast.LENGTH_SHORT).show();
                  //YOUR FIRST RUN CODE HERE
             }
             firstRun = false;
    
             super.onCreate(savedInstanceState);
             //THE REST OF YOUR CODE
    }
    
    0 讨论(0)
提交回复
热议问题