How to pass database adapter to another activity? - android

I'm having some trouble understanding the search dialog in the Android SDK.
The "main activity" of my application provides a button. If the user clicks this button the search dialog is called. The search itself is then done in an async task as it might need some time. So far so good.
The main activity also creates a database adapter object which is used to initialize the database, perform queries, etc. But how can I use this adapter object in the searchable activity?
MAIN activity
// Init database
DatabaseAdapter dba = new DatabaseAdapter();
dba.init();
// open search dialog
if (buttonClick) onSearchRequest();
Searchable activity
Get intent and receive query from search dialog -> OK
How can I use the database adapter again to perform a query?
Do I have to create a new object? Can I pass it somehow from the min activity to the searchable activity, [...]?
Thanks,
Robert

You can create adapter in Application class, and retreieve it in all your activities. That's what I do for my projects.
public class ApplicationClass extends Application {
Adapter adapter.
#Override
public void onCreate(){
adapter=new Adapter();
super.onCreate();
}
public Adapter getAdapter(){
return adapter;
}
}
Then call from Activity:
Adapter adapter=(ApplicationClass)getApplication().getAdapter();
Something like that. ApplicationClass is for your app name. Could be MyAppNameApplication You should create it in your package and then declare in AndroidManifest.xml

An option would be to use a singleton and provide access to the DatabaseAdapter via a static method. Ex:
private static DatabaseAdapter sWritableAdapter = null;
private static DatabaseAdapter sReadableAdapter = null;
public static DatabaseAdapter openForReading(Context ctx) {
if(sReadableAdapter == null)
sReadableAdapter = new DatabaseAdapter(new DatabaseHelper(ctx).getReadableDatabase());
return sReadableAdapter;
}
or for write access:
public static DatabaseAdapter openForWriting(Context ctx) {
if(sWritableAdapter == null)
sWritableAdapter = new DatabaseAdapter(new DatabaseHelper(ctx).getWritableDatabase());
return sWritableAdapter;
}
So in your searchable activity you would write for instance:
DatabaseAdapter adapter = DatabaseAdapter.openForReading(ctx);
adapter.searchSomething();
Marco

You should rather implement an ContentProvider
http://developer.android.com/guide/topics/providers/content-providers.html
They are singletons, and accessible from (almost) everywhere in your application.

Related

Android: How to access from activity to update private variable of another activity

I am trying to do something like that , Firstly , there is a MainActivity which stores courses in ArrayList and these courses are showed by listview.After that , I pass to another activity which is called as ShowDetailActivity with startActivity() to show course details when I click list view element.Then, I pass to another activity which is called EditCourseActivity to edit course which is shown by ShowDetailActivity. The problem is that When I want to edit course , I have to access MainActivity 's Arraylist (private) but I cannot pass with startActivity() because MainActivity did restart (reinstalled) that's why there is no courses on arraylist. The question is How can access from EditCourseActivity to MainActivity 's arraylist to show updated courses ?
Store the course information in a singleton class
public class CourseHolder{
public static CourseHolder instance=null;
public static CourseHolder getInstance(){
if(instance==null){
instance=new CourseHolder();
}
return instance;
}
private Course courses[];
private CourseHolder(){
courses=new Course[10];
}
public void setCourse(int index, Course course){
courses[index]=course;
}
public Course[] getCourses(){
return courses;
}
}
In the EditCourseActivity, after editing, store the updated course information in the copy of CourseHolder
In MainActivity.onResume(), call listView.setAdapter(null), then refresh it with the data inside the CourseHolder
As a generic answer: detach the data from its representation. You can achieve this in many ways:
Singleton wrapper for your array list
To be android specific: wrap your array in a ContentProvider
Use Android SDK SQL database support

Android create static ArrayList

im trying to remove values from an arrayList im my android app, but they keep re-appearing.
My arrayList is in a separate class,
in my Main Activty I create an instance of that class and remove a value from the array.
I exit the Main Activity and return the value re-appears.
My Question is how can I can some kind of static instance of the array class???
//ArrayClass
public class ArrayClass {
public final static ArrayList<String> words = new ArrayList<String>();
public ArrayClass() {
words.add("WORD");
words.add("WORD");
words.add("WORD");
}
//Main Class
ArrayClass wordc = new ArrayClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
wordc.removeWord(0);
}
Orest is correct you do want a singleton pattern, but remember when you access the class's methods you always need to use the getInstance() method.
For example a method within the Class:
public String getWord(index i) {
.......
}
Should be called statically as follows
ArrayClass.getInstance().getWord(i);
NOT like this
wordc.getWord(i);
This guarantees that there is one and only one instance (thus the singleton)
I might be confused on what you are doing but to access the static Array you don't want to create an instance of the class. Everytime you do that you are running the constructor which, in the example code, populates your static Array each time with 3 values.
I don't see exactly what you are trying to accomplish so maybe you could explain that a little better but I'm guessing this really isn't what you want your constructor doing. I think you want to access the Array itself statically
//Main Class
ArrayClass wordc = new ArrayClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
wordc.removeWord(0); //don't need this
ArrayClass.words.remove(0); // would remove the element at index 0
}
But this still wouldn't solve your problem. You need a method inside your ArrayClass class that adds items to your Array. Doing it in your constructor will add these items each time you create a new instance of your class.
If this doesn't answer your question then maybe you can explain your assignment a little better.
Have you tried the Singleton patter? You will have one static reference of ArrayClass and it's internal state won't be violated by activity lifecycle.
public class ArrayClass {
private static ArrayClass instance;
public static ArrayClass getInstance() {
if(instance == null) instance = new ArrayClass();
return instance;
}
//...rest goes as is.

How to call startManagingCursor in non activity Class or in any static method to retrive data from sqlite (in android)?

DBHelper db =new DBHelper(context);
Cursor result = db.weeklyMedicinesTaken();
//WeeklyMedicinesTaken is a function in DBHelper class which returns cursor containing an integer value.
startManagingCursor(result); //this function is a resistance in what i want to do.
while(result.moveToNext())
{
int count=result.getInt(0);
}
result.close();
Actually I have simple classes (non activity classes) in which i want to retrieve data from sqlite and apply some processing and evaluation of data., but the problem is that the code above is working fine in activity but not working in any non activity class or in any static function of activity so that i can call that function from any class.
Any Suggestion Please??
Use getActivity().startManagingCursor(c) or pass an instance of your context to the class inwhich you want to call startManagingCursor()
Lets say your class is sth like this:
Person{
Context mContext;
String name, surname;
Person (Context context){
mContext = context;
}
While creating your Person object you should pass the context like this:
in your onCreate() or somewhere else inside the activity:
Person p = new Person(getActivity());
However, it's not a good practice to manage your cursor outside the activity.
You can examine this tutorial for simple patterns.

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()?

Android: extending android.app.Application

I have a DBHandler class that will be used in several activities to do some crud operations. created a MyApp class (extends Application) to hold one instantiation of the DBHandler.
My DBHandler class needs a Context to create the SQLiteOpenHelper to populate the db, etc.
That's where the problem starts: in my MyApp constructor, I want to instantiate my DBHandler, so I wrote this:
public MyApp() {
super();
dbh = DBHandler(<WHAT DO I PASS HERE>);
}
I tried getApplicationContext(), getBaseContext(), 'this'... nothing seems to be a fully-instantiated context at this point. I get a NPE when the SQLiteOpenHelper tries ctx.getResources().
A workaround: create the DBHandler and set it in the onCreate of my main class. -> UGLY (call me a aesthetician)
Question: is there a way to do it when Android creates MyApp?
Thanks!
Creating your DBHandler in MyApp.onCreate() is the proper way to do what you want.
#Override
public void onCreate() {
super.onCreate();
dbh = new DBHandler(this);
}

Categories

Resources