Minimise SQLite close() calls - android

Intro
I am using the library, SQLCipher in my Android project, which allows me to access a pre-encrypted SQLite v3 database from within my application.
The only downside is that there is currently a lot of overhead when creating a new database connection (getReadableDatabase() and getWritableDatabase()calls), due to all the encryption stuff that goes on every time the database is opened. These calls are currently slowing down my application significantly.
What I am trying to achieve
So, I am seeking to minimise the number of times that I needs to make these calls, by holding a single active connection to my database across all of my activities.
How I intend to achieve this
Instantiate connection to database upon application start
For each activity, maintain a special flag
Whenever an activity is switched to another (via an intent), this boolean flag is set true
Each activity's onDestroy() method will close the application's connection to the database, unless that activity's flag is true (i.e., application isn't being destroyed, we are simply moving to a different activity)
An example
public class ExampleActivity extends Activity {
// Used to determine whether we are destroying the activity due to an intent.
private boolean isIntent = false;
public void someMethod() {
isIntent = true;
Intent intent = new Intent(this, SomeOtherActivity.class);
startActivity(intent);
finish();
}
#Override
public void onDestroy() {
super.onDestroy();
if (!isIntent)
// We haven't started another activity, so we should close the open
// database connection.
DatabaseHelper.close();
}
}
Questions
Are there any issues to this approach that I haven't considered? I haven't seen it done before, so I am wary.
Is there a better way of achieving the desired result?

You can create a singleton class around your subclass of the SQLCipher-based SQLiteOpenHelper. Within the SQLiteOpenHelper, calls to getWritableDatabase() internally cache the returned database object, so key derivation is not occurring each time that method is called.

Related

Android application startup sequence

I am working on an app where I need to bind to a database via IBinder. I planned on putting any framework initialization in my Application subclass since that kind of stuff isn't presentation related and I know that the Application will be instantiated once per app.
public class MyApplication extends MultiDexApplication {
public void onCreate() {
super.onCreate();
// Bind to the db server
Intent intent = new Intent(getBaseContext(), DB.BIND_ADDRESS);
super.bindService(intent,
new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name,
IBinder service) {
DB.start(service);
}
#Override
public void onServiceDisconnected(ComponentName name) {
DB.shutdown();
}
},
Context.BIND_AUTO_CREATE
);
}
}
The problem that I run into is that the call back to my ServiceConnection.onServiceConnected() isn't performed until my activity has started and that's a problem since I need the database available for the activity to display the data. I currently see this behavior.
myApplication.onCreate()
myActivity.onCreate()
myActivity.onStart()
serviceConnection.onServiceConnected()
This is a problem since the database isn't yet connected when the onStart() is invoked on my activity.
I would rather not have to move this infrastructure initialization in the activities. So I have two questions.
Is there a way to block the application.onCreate to wait until
the onServiceConnected() has been invoked? This being single
threaded I don't see how.
Is there a way to tell android not to invoke any onStart() on any
activities prior to my application having completed its
initialization such that I have the following startup sequence
This
myApplication.onCreate()
serviceConnection.onServiceConnected()
myActivity.onCreate()
myActivity.onStart()
or
myApplication.onCreate()
myActivity.onCreate()
serviceConnection.onServiceConnected()
myActivity.onStart()
You'll need to rewrite your code to work with the Android framework. There is no way to wait in onCreate- all the code happens on a single thread, it won't even attempt to start your service until onCreate is finished. I suggest you use onResume or onServiceCreated itself to load the data.
There is no way to do like that.The best solution is to show some type of loading dialog until it connected and fetch from the database

Handle application states (starting/stopping) not activity states

I'm working on my 1st Android app and wondering how to handle activation/deactivation/starting/stopping globally, not on Activity level.
This great article shows states transition for Activities:
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Is there something similar for Application states?
For example at iOS and Windows Phone app there is clear app states separated from activities (views, controllers, whatever).
I'm asking because I want to perform certain operations only once per app loading/exiting not with every activity starting/stopping
The answer is There is Simply No Direct method to do this
rather than in Application Class you can catch these events
#Override
public void onLowMemory()
{
super.onLowMemory();
}
#Override
public void onTerminate()
{
super.onTerminate();
}
So you will have to handle it in all the Activities you will be having
the following methods
onResume()
onStart()
onRestart()
onPause()
onDestroy()
You will have to implement in all Activity to handle for all application
A suggesstion
You can have some Variable in Application class to save application state
say create a variable like
public static boolean isPaused;
and set it from all activity on state change
The question you're asking is applicable for iOS and Windows but not really for Android.
Android doesn't really have a concept of an application as an object, although there's an Application class. Instead, an app is a loose collection of Activities. There are many good reasons for this state of affairs; for example, it supports fast app switching and easy interaction between Activities of different apps.
The best way to coordinate your "app" so that one Activity doesn't try to do something that's already been done is to use SharedPreferences to store app state. Nearly every other way of doing it is less preferred. Even if the system kills off your entire app, SharedPreferences will maintain the current state. The Application object won't.
Also, Android is based on pausing and resuming. An Activity or activities are created, pause, and resume. They may be destroyed, but that's an extreme case. A corollary to this is that apps should not have an exit button; there's no need for one. I sometimes see apps that have one, but what they're really trying to do is shut down a background Service or process. The best way to do that is to have an affordance that says "Sleep" or similar.
Have all activities inherit from the same hierarchy and put whatever you want in OnCreate, OnPause, OnResume, OnStop, OnDestroy and call the super where applicable.
Example
Parent
IamTheParentActivity : Activity
protected void onCreate()
{
setApplicationState(ApplicationState.Running);
}
protected void onPause()
{
setApplicationState(ApplicationState.Paused);
}
private void setApplicationState(Enum ApplicationState)
{
//Some Application Level Variable
Application.State = ApplicationState
}
Children
IamTheChild : IamTheParentActivity
protected void override onCreate()
{
base.OnCreate;
do other stuff
}

Android: How to backup a database when the application gets closed?

I am needing help to determine the right approach. I want to make a backup of an internal database to a location in the external storage every time the whole application gets interrupted or terminated/destroyed. I want to call this method from a central class called Main which extends Application. The reason for that is, that I need to use several activites and I want to call the backup Method only when needed (like described when the whole application gets destroyed or interrupted by another application). I try to avoid calling this backup method in every activity in their onPause() methods.
I thought about starting a service in the onCreate() method of the application, and starting the backup method when the service gets destroyed. But this won't help in the case of an interrupt, as far as I understood the logic behind services. And also the service doesn't seem to start. startService(new Intent(getApplicationContext(), BackupService.class)); Furthermore I don't think it is a good approach to just use the onDestroy() method of a service, this is not what the service class is made for in my opinion.
So summarizing my Question, do you know a better way then using a service, or if not do you know how I should use the service to be able to call a backup only at the point when the whole app (and not only an activity) is interrupted or destroyed.
First of all, if your service "doesn't seem to start", you are probably doing something wrong.
To accomplish your goal make a backup of an internal database to a location in the external storage every time the whole application gets interrupted or terminated/destroyed:
There are three cases in general here.
If you want to do it in the activity layer:
To know when your application is crashed, you need to implement a custom handler to catch the uncaught exceptions.
To know when your activity is "interrupted", the only way is do it in onPause.
To know when your activity is "terminated", the only way is to do it in onDestroy.
This will require you to have a clear navigation and only do it in your "main activity", and all the other activity starts and comes back to it OR use a flag to indicate if the pause was caused by going to another activity.
If you want to do it in the service layer: (Your way of doing it onDestroy won't allow you to detect interrupted case since you will have to start service sticky to keep it running)
You will have to set up a flag on each activity onBind (you will have to bind it and unbind it) to know if it is a crash/interrupt/termination, which will complicate other part of your code.
To avoid running repetitive code, you will have to create a generic base class and extend your other activities from it.
I use this approach to play background music in one of my games, but I guess it works in this scenario as well.
Use a boolean flag to indicate whether or not your app is launching another part of your app.
boolean movingInApp = false;
....
movingInApp = true;
Intent intent...
.....
public void onPause() {
if(!movingInApp) {
//start service
}
}
public void onResume() {
movingInApp = false;
//Stop service
}
By setting the value of movingInApp to true before launching any intent etc, you can prevent your app from starting the service. Remember to set it to false again later in your onResume() method. If the system makes your app go to the background, this will be false, and your service will be started.
Why dont u have all of your activities extend a base activity which in turn extend the android activity class
I the base activity have backupDB method in the onPause
Therefore u dont have to put it in every activity pause method

Android: saving application state when going to the "background"

I have a complex Android app with a decent amount of application state that needs to be persisted (in a specific format). Writing out the data is not an instantaneous operation and so it would be ideal to minimize persisting it unnecessarily.
Because of the persistence overhead it is not practical to persist the state every time it is changed. Ideally, persisting state would be triggered when the app is "backgrounded" by the user tapping the 'home' button or tapping the 'back' button on the app's root Activity (or by an incoming call, etc.). This minimizes persistence overhead while maintaining state consistency from the user's perspective. The question is how can you detect if the app is being "backgrounded"?
The Activity lifecycle calls (onStart, onResume, onPause and friends) don't help as the app has many different activities, any one of which could be active when the user taps 'home'. Furthermore, the calls get called when Activities get pushed, popped (and bottom killed) on the Activity stack and so they don't reflect if the app is going away or not.
So how does an app detect when it is going to the background?
If you want to persist some state when any of your activities goes to the background you could always extend Activity, add two abstact methods which you call in onPause and onResume. Then each one of your Activities which extends this new abstract class would be forced to define saveState() and loadState(). These methods could define what to save and load for each activity.
That is just an example of using inheritance to force your programmers to implement otherwise overlooked methods and techniques methods. You can just tell your programmers, if you ever need to save the state of an activity just extend this type of activity and then the IDE will put them on the path of your design.
package com.yourcompany.yourpackage;
import android.app.Activity;
public abstract class ActivitySaveState extends Activity{
#Override
protected void onPause() {
super.onPause();
saveState();
}
#Override
protected void onResume() {
super.onResume();
loadState();
}
public abstract void loadState();
public abstract void saveState();
}
Also you could instantiate some of the state saving mechanisms for them in the super class (i.e. web service endpoint, DAO or w/e your persistence unit maybe.
#Override
protected void onResume() {
super.onResume();
saveState();
CustomDataAccessObject dao = new CustomDataAccessObject("Activity3");
loadState(dao );
}
public abstract void loadState(CustomDataAccessObject dao);
As far as I got in Android there is no concept of application going to background as a whole. Your application is thought of in terms of a federation of activities/services/... working together. And potentially you could configure it so that it can start from different activities, in different processes, in different tasks, so it's (almost?) impossible to figure out when your application goes to background.
Apart from this, to your question:
MyXxxActivity.onPause is the last safe chance you have to trigger the saving of data that has to be persisted across different "runs" of your application. This is not transient application state, instead it's stuff that goes to DB/File System storage and that you want to retrieve again in the next run.
I assume the application state you mention falls into this category.
So your saving must be triggered from each activity's onPause. If there's any state shared across different activities (e.g. in the Application), it should be collected from each onPause. Or its saving should be triggered as well from each onPause.
If the saving operation takes time, you should not run it on the main (UI) thread. Instead you should hand it off to another thread. Again, assuming this is important state that you do want to be persisted, then it's best to hand this work to a Service (as opposed to an AsyncTask e.g.).
The Activity lifecycle calls (onStart, onResume, onPause and friends) don't help as the app has many different activities
Your activities should be independent enough that you shouldn't need to know when your entire application is in the background. It sounds like you have other design issues that we can't help you with without more specifics.
I suggest managing your data on an activity-by-activity basis. This is suggested in the android docs.
For any activity that alters your persistent state, save that state when leaving the activity.
From http://developer.android.com/reference/android/app/Activity.html
onPause() is where you deal with the user leaving your activity. Most importantly, any changes made by the user should at this point be committed (usually to the ContentProvider holding the data).
This thread is pretty old, just to say onSaveInstanceState of activity is triggered when app is on background or when the user press home button on device. So there, you can save state, on load it on onrestore and so on...

How can i determine when my application is running?

I have an application that uses a Service to fetch data in the background both while the application is running and when it's not.
When it is not running i would like to show a notification when there is new data, but not when the app is running.
How do i determine in my service whether the app is running or not?
I think you want to check whether a certain activity is shown. If that is true, I would use the Activity.onCreate() method to set a flag in the application instance, i.e. extend the class Application with a field "uiRunning" and check this field in your service. onDestroy() should be used to unflag the attribute. Don't forget to use your Application class also in the Manifest.xml
I would agree with the use of onCreate()/onDestroy() for a single Activity application, though an Application with multiple activities would be better off using Application.onCreate()/onTerminate() in order to avoid triggering the uiRunning state when switching activities.
This is dead easy. You use a named Mutex.
Put this in the application you want to check:
bool createdNew;
Mutex mutex = new Mutex(true, #"Global\YourAppNameHere", out createdNew);
if (createdNew)
{
var app = new YourProcess();
app.run();
mutex.Close();
}
Put this in the application that checks to make sure the other app is running:
bool createdNew;
Mutex mutex = new Mutex(true, #"Global\YourAppNameHere", out createdNew);
if (createdNew)
{
Console.WriteLine("App not running");
mutex.Close();
} else {
Console.WriteLine("App is running");
}
Another option is to implement a listener pattern and have your service manage a list of listeners with methods on your service interface for addListener() and removeListener(). Your activity can add itself as a listener after it connects to the service and remove itself onStop() (i.e. when the app is no longer visible to the user or has shutdown completely).
In your service, check the count of listeners. If there are no listeners then you know you should create your notification.
Another way to accomplish is to de-couple your data receiver to a 'service' which will always run in the background. you can have your application bind to the service and will display the data fetched by the service.
The problem with having the application in background is that Android will kill the application once it gets too old. Its always better to have such background running application as service rather then activity.
What i did do was to use a flag in my service, that the root activity sets and clears on onStart/onStop. This works pretty well.
This is how I did it and is working flawlessly with just a few lines of code:
In extended App class:
public static boolean isAppInFront = false;
In you main activity:
#Override
public void onStart() {
super.onStart();
MyApplication.isAppInFront = true;
}
#Override
public void onStop() {
super.onStop();
if (isFinishing())
MyApplication.isAppInFront = false;
}

Categories

Resources