Ormlite inside Intentservice - ClassCastException - android

I am trying to use Ormlite for Database handling from an intentservice. I have read about using an Application as subclass. I have tried the following
The application class:
public class MyApplication extends Application {
private volatile DatabaseHelper databaseHelper = null;
#Override
public void onCreate() {
super.onCreate();
}
public DatabaseHelper getHelper() {
if (databaseHelper == null) {
databaseHelper = OpenHelperManager.getHelper(this, DatabaseHelper.class);
}
return databaseHelper;
}
}
In the intent service I defined:
private DatabaseHelper databaseHelper;
And in the onHandleIntent() method of the intentservice I have tried:
databaseHelper = ((MyApplication) getApplicationContext()).getHelper();
However I am getting ClassCastException, from Application to MyApplication
Can someone explain to me what I'm doing wrong?

Found the problem. I was declaring the application in the manifest as a different one from my main application.
What I needed is to modify the main application in AndroidManifest.xml. I pointed the main application to the custom application (MyApplication) that I created
Add this:
<Application android:name=".MyApplication">

Related

Cannot cast Application to CustomApplication

I have a CustomApplication extends Application class, which is registered in AndroidManifest
<application
....
// Please, pay attention that I got this in my Manifest
android:name=".CustomApplication">
And at different part of my application, both some activities and services I do
getApplication()/getApplicationContext() then cast it to CustomApplication and it crashes in production on a variety of devices/sdk versions(beginning at android 6) due to a class cast exception. Caused by: java.lang.ClassCastException
Example:
class CustomApplication extends Application{
...
public static CustomApplication with(Context context) {
return (CustomApplication) context.getApplicationContext(); //crashes here
}
}
and service example:
class CustomService extends IntentService{
...
#Override
rotected void onHandleIntent(#Nullable Intent intent) {
CustomApplication app = CustomApplication.from(getApplication());
// tried getApplicationContext() also
}
}
and activity example:
class CustomActivity extends AppCompatActivity{
...
#Override
protected void onCreate(...){
CustomApplication app = CustomApplication.with(this);
}
What I've tried:
Tried services with different process=":process"
Tried deep linking with different launchModes
Tried activities with taskAffinity
launching from push notifications
process cleaning with system tray(on device), ps kill int adb shell
nothing helps me to reproduce an issue on emulator
I don't use Instant Run also (never used it)
Please don't provide me with suggests of using static application context instance
You can keep a static reference of your CustomApplication like below. You don't need to cast in the following way.
public class CustomApplication extends Application {
private static CustomApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static CustomApplication getContext() {
return instance;
}
}
Then call CustomApplication.getContext();
You need to define your custom application in the manifest as follow:
<application
....
android:name="my.package.path.CustomApplication">
... activities ....
</application>
Also, you are getting an instance of a class that extends Application, not Context, that being said you should call this the following way:
CustomApplication customApplication;
customApplication = (CustomApplication)getApplication();
What you might have to apply in case you have BroadcastReceiver(No context available) is:
customApplication = (CustomApplication)getApplicationContext().getApplication();

Prevent multiple instantiation of an activity

Is it possible to make an activity singleton?
I have found many resources that just tell to use android:launchMode="singleInstance" or singleTask, but I would constructor to be called only once.
Ideally, I would like to be able to specify custom constructor/builder method e.g. getInstance()
You could store your references in Application instead of an Activity. The application class is de facto a singleton. You only need to define your access methods.
public class BaseApplication extends Application {
private static BaseApplication sInstance = null;
public synchronized static BaseApplication getInstance() {
return sInstance;
}
public synchronized static void setInstance(BaseApplication app) {
sInstance = app;
}
public BaseApplication() {
}
#Override
public void onCreate() {
super.onCreate();
setInstance(this);
}
Now you can access it by calling BaseApplication.getInstance(). As a bonus the Application extends Context so now you have an application context reference anywhere you want (safe to use pretty much everywhere except inflating layouts).
Don't forget to define this class as the base application class in your manifest:
<application
android:name="com.yourapp.BaseApplication">
Usually they do as follows:
1) define what comprise the Activity state
2) Save the state in onSaveInstanceState
3) Restore the state in onCreate or in onRestoreInstanceState

Releasing ORMLite helper on #Singleton

I have a #Singleton class where I've injected an instance of OrmLiteSqliteOpenHelper. Do I actually ever need to call the OpenHelperManager.releaseHelper()? In case I do, where and how should it be done as the class doesn't extend any Android base class where I could get to the onDestroy?
There is an ORMLite example Android project which demonstrates this called HelloAndroidNoBase. I'd check it out.
The relevant code section from the main Activity is included below. You'll need to have this sort of code in each one of your Activity or other classes that uses the database.
If your class does not have an onDestroy() method then you need to add one and call it from one of the other classes that does have onDestroy(). The main Activity is a good place for this. So your MainActivity.onDestroy() would call yourClass.onDestroy() when the application is shutting down.
public class HelloNoBase extends Activity {
private DatabaseHelper databaseHelper = null;
#Override
protected void onDestroy() {
super.onDestroy();
if (databaseHelper != null) {
OpenHelperManager.releaseHelper();
databaseHelper = null;
}
}
private DatabaseHelper getHelper() {
if (databaseHelper == null) {
databaseHelper = OpenHelperManager.getHelper(this,
DatabaseHelper.class);
}
return databaseHelper;
}
}

Accessing Application class from Activity crashes

I am relatively new to Android programming. So please, forgive me for writing or asking anything stupid. I am working on an Android application in which I am using SQLite database to store data. I need to access this database from more Activities and after some research I have concluded that the best way to do so is using an Application class. But this is where my program stops working.
I have my Application class:
import android.app.Application;
public class MyApplication extends Application {
public CONTACT_DB = new CONTACT_DB(this);
}
where CONTACT_DB class is where I have defined my database and has this constructor:
private final Context context;
private DatabaseHelper DBHelper;
public CONTACT_DB(Context ctx) {
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
Now in my Activity, where I need to access this database
public class Add_contact extends Activity {
CONTACT_DB db;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_contact_layout);
MyApplication appState = ((MyApplication)getApplicationContext());
db = appState.db;
}
}
My program works fine, but when it gets to line
MyApplication appState = ((MyApplication)getApplicationContext());
then it crashes. I tried to use just a simple int instead of my CONTACT_DB class and it still srashes. Any ideas?
Have you declared your custom application class in the manifest?
For example:
<application
android:name="com.yournamespace.appname.MyApplication"
android:icon="#drawable/icon"
android:label="#string/app_name">

Using singleton class for sharing instance of database between activities?

Hey! I want to use a singleton class, because if I open the database every activity I get "Leak found"( that happens because I open the database even if it is already open ) . I create a singleton class , but I don't know how should I use it.
Here is my class:
package com.ShoppingList;
import com.ShoppingList.databases.DbAdapter;
public class DbManager {
DbAdapter db;
// singleton
private static DbManager instance = null;
private DbManager() {
}
public static DbManager getInstance() {
if (instance == null)
instance = new DbManager();
return instance;
}
public void setinstance(DbAdapter db){
this.db=db;
}
public DbAdapter getinstancedb(){
return db;
}
}
In the first activity I put :
db = new DbAdapter(this);
db.open();
DbManager.getInstance().setinstance(db);
and for the next activity : DbManager.getInstance().getinstancedb(); but I get force close for second activity.
Can anyone help me how to use it? Thanks...
You can extend Application class and create there an instance of DbAdapter. This way it will be shared by all your activities.
Because db has the same context and life cycle of your first activity. Make your methods public and make them do all the setup/teardown necessary to return your desired result.
regarding the leak warning. Are you closing your db manager connection in onDestroy()?

Categories

Resources