I am using ormLite to store data on device.
I can not understand why but when I store about 100 objects some of them stores too long time, up to second.
Here is the code
from DatabaseManager:
public class DatabaseManager
public void addSomeObject(SomeObject object) {
try {
getHelper().getSomeObjectDao().create(object);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
public Dao<SomeObject, Integer> getSomeObjectDao() {
if (null == someObjectDao) {
try {
someObjectDao = getDao(SomeObject.class);
} catch (Exception e) {
e.printStackTrace();
}
}
return someObjectDao;
}
Any ideas to avoid this situations?
Thanks to Gray!
Solution is, as mentioned Gray, using callBatchTasks method:
public void updateListOfObjects (final List <Object> list) {
try {
getHelper().getObjectDao().callBatchTasks(new Callable<Object> (){
#Override
public Object call() throws Exception {
for (Object obj : list){
getHelper().getObjectDao().createOrUpdate(obj);
}
return null;
}
});
} catch (Exception e) {
Log.d(TAG, "updateListOfObjects. Exception " + e.toString());
}
}
Using this way, my objects (two types of objects, 1st type - about 100 items, 2nd type - about 150 items) store in 1.7 sec.
See the ORMLite documentation.
Related
I would like to wrap a synchronous method from parse.com mainly ParseObject.save() into a RxJava wrapper. I have come up with the below:
public Observable<Void> uploadFix(final ParseObject parseObject) {
return Observable.defer(new Func0<Observable<Void>>() {
#Override
public Observable<Void> call() {
try {
return Observable.just(fix.save());
} catch (ParseException e) {
return Observable.error(e);
}
}
});
}
This is giving me an error: Observable cannot be applied to void.
Basically is there any way to wrap this call with RxJava and get notified if the save is successful?
fix.save() returns void so you can't use it as an argument to Observable.just(). You can return a boolean instead.
public Observable<Boolean> uploadFix(final ParseObject parseObject) {
return Observable.defer(new Func0<Observable<Boolean>>() {
#Override
public Observable<Boolean> call() {
try {
fix.save();
return Observable.just(true);
} catch (ParseException e) {
return Observable.error(e);
}
}
});
}
you could also use a Completable. It is used when you don't except a return-value. If RxJava for Android will bump-up to version 2, you can not use Observabl anymore, because null values are not allowed anymore.
Please look at my example. I am using RxJava2-RC5 for testing. Test should complete within 2 seconds + overhead.
#org.junit.Test
public void name() throws Exception {
Completable completable = Completable.fromAction(() -> doWorkSync());
TestObserver<Void> test = completable.test();
test.assertComplete();
}
private void doWorkSync() {
// simulate work
try {
Thread.sleep(2_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I try to make simple test. I have json response from REST API with ~250 objects shops and the same response in file but first shop has different name. First step is load JSON file with ~250 shops and save in local db using ORMLite. Next step is connect with API and get the same response. New json response is parse and UPDATE exist elements in database. What is result?
Now I go to simple Activity with ListView and call getShopsAll(). This method return old data before update. Why?
This is method to save shop in database:
public void createShop(final ArrayList<ModelSklep> list) throws Exception {
getDaoShop().callBatchTasks(new Callable<Void>() {
#Override
public Void call() {
for(ModelSklep item : list) {
createShop(item);
if(item.getHoursList().size() > 0) {
createHours(item.getHoursList());
}
}
return null;
}
});
}
Method createshop:
public boolean createShop(ModelSklep item) {
try {
getDaoShop().createOrUpdate(item);
return true;
} catch (SQLException e) {
return false;
}
}
Method getShopAll:
public ArrayList<ModelSklep> getShopAll() {
try {
return (ArrayList<ModelSklep>) getDaoShop().queryBuilder().orderByRaw(
"nazwaPelna COLLATE LOCALIZED ASC").query();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
Object is updating. But getShopAll() return old data object.
Clear cache after update doesn't work.
Help. I don't know how resolve this problem.
[Edit]
public Dao<ModelSklep, Integer> getDaoShop() {
if(modelShopDao == null) {
try {
modelShopDao = getDao(ModelSklep.class);
modelShopDao.setObjectCache(true);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
return modelShopDao;
}
I am a beginner in android programming.
I want to use the hidden method "getState()" of "com.android.internal.telephony.call" package to manage the state of an outgoing call such as activating, ringing, answering, rejecting and disconnecting.
But there is an error in the following code on the line indicated by "**".
Any help?
My code is :
import com.android.internal.telephony.*;
public class MainActivity extends Activity {
Class myclass;
ClassLoader cloader;
Method f;
Object o;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cloader = this.getClass().getClassLoader();
try {
myclass = cloader.loadClass("com.android.internal.telephony.Call");
// No error generated. "Call" class will be loaded.
}
catch (Exception e)
{
System.out.println(e.toString());
}
try {
f = myclass.getMethod("getState", null);
// No error generated.Method "f" will be assigned
} catch (Exception e) {
System.out.println(e.toString());
}
Constructor constructors[] = myclass.getDeclaredConstructors();
// There is one constructor only
Constructor constructor = null;
for (int i=0; i<constructors.length;i++)
{
constructor = constructors[i];
if (constructor.getGenericParameterTypes().length == 0)
break;
}
constructor.setAccessible(true);
try {
o = constructor.newInstance(null);
//*****an exception generated here.
//*****Exception is "java.lang.instantationexception"
}
catch (Exception e) {
System.out.println(e.toString());
}
try {
f = myclass.getMethod("getState", null);
// No error
} catch (Exception e) {
System.out.println(e.toString());
}
}
Don't try to call private members like this. It will not work across Android versions and even across manufacturer customized ROMs of the same version.
I'm currently stuck with the following situation;
Basically I've got a Work class, which has a ForeignCollection of WorkTasks.
I'd like to simply receive all WorkTasks, linked to Work object.
If I query for all WorkTasks, I do get a list of results but with 'work = null'. So it can't make any link to the correct Work object.
Resulting in no results with querying for the work_id and an empty list in Work itself.
I've seen examples and questions about this countless of times but apparently im missing out on something.
Below is the code that im using which is relevant;
The DatabaseHelper;
#Override
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
try {
applicantDao = DaoManager.createDao(connectionSource, Applicant.class);
educationDao = DaoManager.createDao(connectionSource, Education.class);
workDao = DaoManager.createDao(connectionSource, Work.class);
workTaskDao = DaoManager.createDao(getConnectionSource(), WorkTask.class);
onlinePersonDao = DaoManager.createDao(connectionSource, OnlinePerson.class);
institutionDao = DaoManager.createDao(connectionSource, Institution.class);
lessonDao = DaoManager.createDao(connectionSource, Lesson.class);
TableUtils.createTable(connectionSource, Applicant.class);
TableUtils.createTable(connectionSource, Education.class);
TableUtils.createTable(connectionSource, Work.class);
TableUtils.createTable(connectionSource, Institution.class);
TableUtils.createTable(connectionSource, Lesson.class);
TableUtils.createTable(connectionSource, OnlinePerson.class);
TableUtils.createTable(connectionSource, Reference.class);
TableUtils.createTable(connectionSource, WorkTask.class);
[....]
public Dao<WorkTask, Integer> getWorkTaskDao() {
if (null == workTaskDao) {
try {
workTaskDao = getDao(WorkTask.class);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
}
return workTaskDao;
}
The database manager:
public List<Experience> getAllWork() {
List<Experience> exp = null;
try {
exp = getHelper().getWorkDao().queryForAll();
} catch (SQLException e) {
e.printStackTrace();
}
return exp;
}
public List<WorkTask> getAllWorkTask() {
List<WorkTask> workTask = null;
try {
workTask = getHelper().getWorkTaskDao().queryForAll();
} catch (SQLException e) {
e.printStackTrace();
}
return workTask;
}
public List<WorkTask> getWorkTaskByWorkId(int workId) {
List<WorkTask> workTasks = null;
try {
workTasks = getHelper().getWorkTaskDao().queryForEq("work_id", workId);
} catch (SQLException e) {
e.printStackTrace();
}
return workTasks;
}
public void addWork(Collection<Work> jobs) {
try {
for (Experience work : jobs) {
Work w = (Work) work;
// Add nested child first
this.addInstitution(w.institution);
this.addWorkTask(w.tasks);
getHelper().getWorkDao().createOrUpdate(w);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void addWorkTask(Collection<WorkTask> worktasks) {
try {
for (WorkTask wt : worktasks) {
getHelper().getWorkTaskDao().createOrUpdate(wt);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
The list from the work model (gets a pre-filled id from an abstract parent):
#ForeignCollectionField(eager = true)
#SerializedName("tasks")
public Collection<WorkTask> tasks;
public ArrayList<WorkTask> getTasks(){
ArrayList<WorkTask> taskList = new ArrayList<WorkTask>();
Iterator iterator = tasks.iterator();
while(iterator.hasNext()){
WorkTask task = (WorkTask) iterator.next();
taskList.add(task);
}
return taskList;
}
The WorkTask :
public class WorkTask {
/**
* Auto-incremented id for the ORMLite-SQLite database
*/
#DatabaseField(generatedId = true)
public int id;
/**
* Foreign field id for the ORMLite-SQLite database
*/
#DatabaseField(foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true, columnName = "work_id")
public Work work;
And finally all the things that are failing me:
ArrayList<WorkTask> tasks_iterated = work.getTasks();
ArrayList<WorkTask> tasks_id = (ArrayList<WorkTask>) DatabaseManager.getInstance()
.getWorkTaskByWorkId(work.id);
ArrayList<WorkTask> tasks = (ArrayList<WorkTask>) DatabaseManager.getInstance().getAllWorkTask();
This eventually leaves me with:
tasks_iterated = empty
tasks_id = empty
tasks = a full list of my tasks but all with the attribute 'work = null' so I can't place them to the correct Work object.
Fixed it by changing my adding method to:
public void addWorkTask(Collection<WorkTask> worktasks, Work work) {
try {
for (WorkTask wt : worktasks) {
wt.work = work;
getHelper().getWorkTaskDao().createOrUpdate(wt);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
Not sure if it's the only way to do this though. Seems a bit weird i'd have to do this manually.
With API16 the new WAL (Write Ahead Logging) was introduced in Androids SQLiteDatabase class. I would like to test if WAL is enabled for a SQLite database. The app runs on older Android releases too, so I need a wrapper class for these new functions in SQLiteDatabase. The functions are:
public boolean isWriteAheadLoggingEnabled()
public boolean enableWriteAheadLogging()
public void disableWriteAheadLogging ()
In the Android Developer Blog I did find an article for a wrapper class that wraps new classes. What I didn't find is a wrapper for new methods in an already existing class. How should I do that?
The constructor for SQLiteDatabase is private so your're not going to be able to extend it and add "wrappers" to the class itself. You can however just write a "helper" wrapper like so:
public class WALWrapper {
private boolean mAvailable;
private Method mIsWriteAheadLoggingEnabled;
private Method mEnableWriteAheadLogging;
private Method mDisableWriteAheadLogging;
private final SQLiteDatabase mDb;
public WALWrapper(SQLiteDatabase db) {
mDb = db;
mAvailable = false;
try {
mIsWriteAheadLoggingEnabled =
SQLiteDatabase.class.getMethod("isWriteAheadLoggingEnabled");
mEnableWriteAheadLogging =
SQLiteDatabase.class.getMethod("enableWriteAheadLogging");
mDisableWriteAheadLogging =
SQLiteDatabase.class.getMethod("disableWriteAheadLogging");
mAvailable = true;
} catch (NoSuchMethodException e) {
}
}
/**
* Returns <code>true</code> if the {#link #isWriteAheadLoggingEnabled()},
* {#link #enableWriteAheadLogging()} and {#link #disableWriteAheadLogging()}
* are available.
* #return <code>true</code> if the WALWrapper is functional, <code>false</code>
* otherwise.
*/
public boolean isWALAvailable() {
return mAvailable;
}
public boolean isWriteAheadLoggingEnabled() {
boolean result = false;
if (mIsWriteAheadLoggingEnabled != null) {
try {
result = (Boolean) mIsWriteAheadLoggingEnabled.invoke(mDb);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
return result;
}
public boolean enableWriteAheadLogging() {
boolean result = false;
if (mEnableWriteAheadLogging != null) {
try {
result = (Boolean) mEnableWriteAheadLogging.invoke(mDb);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
return result;
}
public void disableWriteAheadLogging() {
if (mDisableWriteAheadLogging != null) {
try {
mDisableWriteAheadLogging.invoke(mDb);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
}
}