In my Android project i use Azure Mobile Services SDK and the way i make queries to the local sqlite database is like the following:
(example taken from http://azure.microsoft.com/en-us/documentation/articles/mobile-services-android-get-started-data/).
The problem is that i get the following errors:
1)com.microsoft.windowsazure.mobileservices.table.sync.localstore.MobileServiceLocalStoreException: java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed
2) A SQLiteConnection object for database 'LocalDatabase' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed
3) java.util.concurrent.ExecutionException: com.microsoft.windowsazure.mobileservices.table.sync.localstore.MobileServiceLocalStoreException: java.lang.IllegalStateException: attempt to re-open an already-closed object
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
final MobileServiceList<ToDoItem> result = mToDoTable.where().field("complete").eq(false).execute().get();
runOnUiThread(new Runnable() {
#Override
public void run() {
mAdapter.clear();
for (ToDoItem item : result) {
mAdapter.add(item);
}
}
});
} catch (Exception exception) {
createAndShowDialog(exception, "Error");
}
return null;
}
}.execute();
In this implementation there is no Cursor or SQLiteOpenHelper object to close. What could i do?
Thank you!
I think this is because you are getting the result in one thread but trying to use that same result in the UI thread. One possible method is to use Broadcast or Eventbus to send the data back to the UI once the operation completes:
Here is sort of what I would do:
Futures.addCallback(mToDoTable.where().field("complete").eq(false).execute(), new FutureCallback() {
#Override
public void onSuccess(Object result) {
//Do something with result
//I would use event bus or broadcast here to notify the UI
}
#Override
public void onFailure(Throwable t) {
}
});
If this doesn't work, I would use the debugger and put a break point on that execute().get() line and see what is happening internally.
Here is another possible way to do it:
mToDoTable.where().field("complete").eq(false).execute(new TableQueryCallback<Object>() {
#Override
public void onCompleted(List result, int count, Exception exception, ServiceFilterResponse response) {
}
});
Related
I already asked this as a part of question multi threadaing with room database.
I am accessing room database from multiple threads in android however using same instance of databse in all threads.
new Thread(new Runnable(){
db.getInstance().taskdao().insertAll(list)
}).start();
new Thread(new Runnable(){
List<Task> data = db.getInstance().taskDao.loadAll();
}).start();
However data returned is null and I guess loadAll() is getting exeucted before insertAll() completes. Note that in actual code I am using Rxjava and hence I make sure that I read data after loadAll() is completed. Why this happening since sqlite enables lock to make sure serialize access.
If you try to read immediately after wrinting try to set a callback.
You must wait till function of inserting completes.
Suppose it takes 10ms to write into db and 5ms to start the thread and go to next thread to start (the one that reads). The reading thread starts reading at 6th ms while writing is not yet completed and will return unexpected result.
Better to use an AsyncTask to handle callback.
Simple example:
class Task extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
db.getInstance().taskdao().insertAll(list);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
CallBack c = (CallBack) context; // your activity that implements context
c.onComplete();
}
}
and for interface and overriding:
interface CallBack {
void onComplete();
}
and implement it in your activity:
#Override
public void onComplete() {
//Now read it
}
I have over 10 fragments that execute the same kind of task which is :
Retrieving the Data from the server using Retrofit
Starting an Async Task to update the Database (Using ORMLite)
Once the Database is updated, retrieving the new data from the Database
Notify Dataset has changed in the adapter
I'm wondering if it's useless to put the update database code inside an AsyncTask within my fragment once I retrieve the data from the server?
I have trouble understanding what run on the UI thread and what doesn't and should be started as his own thread through an AsyncTask
Here my code:
private void getLocalIncidentTemplate() {
mIncidentTemplate.clear();
mIncidentTemplate.addAll(GenericDAO.getInstance(EntityGroup.class).queryForAll());
Collections.sort(mIncidentTemplate);
Log.e(TAG, "Incident Template count:" + mIncidentTemplate.size());
mListAdapter.notifyDataSetChanged();
spinner.setVisibility(View.GONE);
}
private void getRemoteIncidentTemplate() {
Call<EntityIncident> call = meepServices.getIncidentTemplate();
call.enqueue(new Callback<EntityIncident>() {
#Override
public void onResponse(Call<EntityIncident> call, Response<EntityIncident> response) {
if (response.isSuccessful()) {
new updateIncidentTemplateTask().execute(response.body());
}
}
#Override
public void onFailure(Call<EntityIncident> call, Throwable t) {
t.getStackTrace();
Log.e(TAG, t.toString());
Utils.showToastMessage(getActivity(), "Error retrieving Incidents", true);
}
});
}
private class updateIncidentTemplateTask extends AsyncTask<EntityCategories, Void, Boolean> {
#Override
protected Boolean doInBackground(EntityCategories... params) {
updateIncidents(params[0]);
return true;
}
protected void onPostExecute(Boolean b) {
getLocalIncidentTemplate();
spinner.setVisibility(View.GONE);
}
}
Here is the Database Update Using ORMlite:
private void updateIncident(EntityCategories categories) {
try {
categories.setId("MobilePlan");
//Update base categories
GenericDAO.getInstance(EntityCategories.class).addOrUpdate(categories);
for (EntityCategories.EntityCategory currentCategory : new ArrayList<>(categories.getCategories())) {
if (currentCategory.getmPlans() != null) {
for (EntityPlan myPlan : new ArrayList<>(currentCategory.getmPlans())) {
EntityPlan oldPlan = GenericDAO.getInstance(EntityPlan.class).queryById(String.valueOf(myPlan.getmId()));
myPlan.setCategories(currentCategory);
if (oldPlan != null) {
if (!myPlan.getmDateModification().equals(oldPlan.getmDateModification())) {
GenericDAO.getInstance(EntityPlan.class).addOrUpdate(myPlan);
}
} else {
GenericDAO.getInstance(EntityPlan.class).addOrUpdate(myPlan);
}
}
} else {
continue;
}
GenericDAO.getInstance(EntityLabel.class).addOrUpdate(currentCategory.getmLabel());
currentCategory.setCategories(categories);
GenericDAO.getInstance(EntityCategories.EntityCategory.class).addOrUpdate(currentCategory);
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG, "DATA updated");
}
For your particular case, you should use the AsyncTask to retrieve data from the backend and place it in the database.
Remember that AsyncTask has three main methods:
onPreExecute() that runs on the UI thread. Useful when you need to prep something that requires UI thread (touching views and whatnot)
doInBackGround() this runs on background thread
onPostExecute() runs also on the UI thread.
In onPostExecute() you could notify your adapter of the new data.
If I were you, I'd use loaders to get notified and retrieve the data off the database. So that the complete chain would be some:
AsyncTask pulls data from the backend and stores it in the database
Your loader will get notified that something changed inside the database and will pull the data from it and call onLoadFinished() method inside your activity/fragment
onLoadFinished() passes the data to the view adapter.
I haven't gone into detail as to how to implement this. I just presented the overall architecture.
I have trouble understanding what run on the UI thread and what doesn't and should be started as his own thread
The short answer:
Everything that might block the UI thread (in other words, might take time) should run on a worker thread (threadpool or dedicated)
DB actions and network requests are classic examples for actions that should always run asynchronously.
In your case I would just use an ORM to wrap all the interaction with the DB, such as ORMlite or any other you find more suitable, in that case you will not have to concern yourself with the inner workings and just provide callbacks for when your calls have finished (successfully or not)
The goal:
Using Google App Engine server and Android client, I'm trying to put on the Google map at the Android client Users overlays. Every 30 seconds I'm polling the server and getting Vector that contains users and adding it to the map.
Current status:
I'm dong all that using in one new thread, So after running the app I got:
weird behaviors(delayed overlays, multiple overlays) and after that crushed with ConcurrentModificationException.
After reading a bit i figured out that I need to work with AsyncTask.
Correct me if I'm wrong,But I understand that everything done in the Activity at at onCreate is "running" in UIhread so I need to put the "Logic" (All the Network handling) in doInBackground and all the UI Handling like putting overlays on the map in onPostExecute.
My Question are:
1) In the current status I'm doing:
new Thread()
{
#Override
public void run()
{
super.run();
while(true)
{
SystemClock.sleep(30000);
Vector responseFromServer = getUsersVectorFromServer();
putNewOnlineUserOnTheMap();
}
}
}.start();
What is the right way to convert this To AsyncTask?
Do I poll the server still using new thread in the doInBackground or there is right way to do this?
2) Is there a specific list of what counts as UI to put in onPostExecute or any concepts list?
In my case I guess that in need to put putNewOnlineUserOnTheMap() in onPostExecute.
Thanks.
Something similar to the following:
class UpdateTask extends AsyncTask<Void, Vector, Void>{
#Override
protected Void doInBackground(Void... params) {
// this is running in a background thread.
while (!isCancelled()) {
SystemClock.sleep(30000);
Vector responseFromServer = getUsersVectorFromServer();
// send the result back to the UI thread
// onProgressUpdate will be called then
publishProgress(responseFromServer);
}
return null;
}
#Override
protected void onProgressUpdate(Vector... values) {
// this is executed on the UI thread where we can safely touch UI stuff
putNewOnlineUserOnTheMap(values[0]);
}
}
You can't use the result of the task since the task is finished then. But you can use the progress publishing mechanism to get periodic results. If you use it like that and do the modification on the UI thread you should not get ConcurrentModificationException because you do the modifications on the one thread that can safely modify the UI.
One thing to note here: create new instances of your Vector in the background thread and then use it to update the UI. But don't touch the same object afterwards in the backgroundthread. That way you don't need any synchronization since after the background thread sends it away it is only the UI thread that touches it. (and you could use a simple ArrayList instead of a Vector)
AsyncTask uses generics and varargs.The parameters that are passed to the asyntask are . TypeOfVariableArgumentsParameters is passed into the doInBackground(), ProgressParam is used for progress information and ResultParam must be returned from doInBackground() and is passed to onPostExecute() as parameter.
example:--
protected class ParsingTask extends AsyncTask> {
private ProgressDialog loadingDialog = new ProgressDialog(JsonParserActivity.this);
protected void onPreExecute() {
loadingDialog.setMessage("loading app store..");
loadingDialog.show();
}
#Override
protected ArrayList<Items> doInBackground( Context... params ) {
// do ur process here.
return result;
}
if (!this.isCancelled()) {
}
return result;
}
#Override
protected void onProgressUpdate(String... s) {
super.onProgressUpdate(s);
Toast.makeText(getApplicationContext(), s[0], Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute( ArrayList<Items> response ) {
//if u r dealing with list view and adapters set the adapter here at the onPostExecute()
loadingDialog.dismiss();
}
#Override
protected void onCancelled() {
super.onCancelled();
Toast.makeText(getApplicationContext(), "The operation was cancelled", 1).show();
}
}
You can use AsyncTask like below. Hope this will help you..
Class YourClass{
void YourClass(){
NetworkTask nT = new NetworkTasK();
nT.execute();
}
}
protected class NetworkTask extends AsyncTask<Void, String, Boolean>
{
#Override
protected Boolean doInBackground(Void... params)
{
try
{
String response;
while(keepreceiving)
{
response = in.readLine();//Prog Counter stops here until getting i/p.
if(response != null)
yourFunctionForResponse(response);
}
}
catch (Exception ex)
{
}
return null;
}
private void yourFunctionForResponse(String response){
//things to do....
}
}
You may also try runOnUiThread(Runnable action) along with this to implement your work.
I'm new to Android development. I've be working on Swing and SWT for several years. Both Swing and SWT has a stratage to execute code in UI thread sync and async. The typical usage is doing some time-consume staff in one thread then display the result in UI thread async.
So my question is, is there similiar stratage in Android? Here is my code. Parameter runnable is some time-consume code. This method will display a waiting dialog during the execution then EXPECT to show a Toast after it is finished. But the Toast need to be show in UI thread. So how to do that?
public static void showWaitingDialog(final Activity parent, final Runnable runnable, String msg) {
if (StringUtils.isEmpty(msg)) {
msg = "processing...";
}
final ProgressDialog waitingDialog = ProgressDialog.show(parent, "Please Wait...", msg, true);
// execute in a new thread instead of UI thread
ThreadPoolUtil.execute(new Runnable() {
public void run() {
try {
// some time-consume operation
runnable.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
waitingDialog.dismiss();
}
// TODO: How to display a Toast message here? execute some code in UI Thread.
}
});
}
And is there some words about Android UI system? Such as is it Thread-Safe, how thread works together and so on. Many Thanks!
There are several ways for doing that,
AsyncTask -
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers. Example for using AsyncTask
Service -
A Service is an application component representing either an
application's desire to perform a longer-running operation while not
interacting with the user or to supply functionality for other
applications to use. Example for Using Service.
IntentService -
IntentService is a base class for Services that handle asynchronous
requests (expressed as Intents) on demand. Clients send requests
through startService(Intent) calls; the service is started as needed,
handles each Intent in turn using a worker thread, and stops itself
when it runs out of work. Example for using IntentService.
You can use AsyncTask like this.
To call AsyncTask
new getAsynctask().execute("");
and here is the class for geting result.
class getAsynctask extends AsyncTask<String, Long, Integer> {
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(Pass.this, null, "Please wait...");
}
protected Integer doInBackground(String... params) {
try {
// do your coding
return null;
} catch (Exception e) {
return null;
}
}
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
try {
if (loading != null && loading.isShowing())
loading.dismiss();
} catch (Throwable t) {
Log.v("this is praki", "loading.dismiss() problem", t);
}
}
}
Whenever you are working with Separate thread which is not your UI thread the best way is to use Handler. Whenever you want to intimate user from your Thread, suppose a progress then send a message to Handler to so. Inside Handler you can handle message and write a code snippet to Change anything on UI. This is the preferred way for Android. see these link1 , link2 & link3
You use this AsynTask as a inner class of your activity. In do in background do the time consuming task you want to do and then in on postexecute you can show the text message.
call this from your main activity
initTask = new InitTask();
initTask.execute(this);
protected class InitTask extends AsyncTask<Context, Integer, String> {
#Override
protected String doInBackground(Context... params) {
// Do the time comsuming task here
return "COMPLETE!";
}
// -- gets called just before thread begins
#Override
protected void onPreExecute() {
super.onPreExecute();
}
// -- called from the publish progress
// -- notice that the datatype of the second param gets passed to this
// method
#Override
protected void onProgressUpdate(Integer... values) {
}
// -- called if the cancel button is pressed
#Override
protected void onCancelled() {
super.onCancelled();
}
// -- called as soon as doInBackground method completes
// -- notice that the third param gets passed to this method
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Show the toast message here
}
}
Use a handler:
static final int SHOW_TOAST = 0;
public static void showWaitingDialog(final Activity parent, final Runnable runnable, String msg) {
if (StringUtils.isEmpty(msg)) {
msg = "processing...";
}
final ProgressDialog waitingDialog = ProgressDialog.show(parent, "Please Wait...", msg, true);
// execute in a new thread instead of UI thread
ThreadPoolUtil.execute(new Runnable() {
public void run() {
try {
// some time-consume operation
runnable.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
waitingDialog.dismiss();
}
handler.sendMessage(handler.obtainMessage(SHOW_TOAST));
}
});
}
public Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_TOAST:
//Toast here
break;
}
}
};
The Painless threading article from the android developer resources provides different alternatives depending on the specific SDK version.
I have listed of products with different category. I have to sort them. Because of the queries, It is taking more time to load. Between two activities, the screen is coming black. I want to run the query in the background. How can I do that and how to use its result in main activity?
private class InsertTask extends AsyncTask {
String cat;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(String... params) {
Boolean success = false;
try {
category(cat);
success = true;
} catch (Exception e) {
if(e.getMessage()!=null)
e.printStackTrace();
}
return success;
}
#Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
}
private void category(String category) {
try{
Cursor1 = mDbHelper.fetchcategory(category);
}catch(Exception e){
Log.v("Excep", ""+e);
}
}
And when called
InsertTask task = new InsertTask();
task.execute();
I have listed the category in buttons. How can I get the values then?
You should use AsyncTask for that. And some more info.
Its good you have thought of AsyncTask. Firstly, you can declare this class as inner in you class activity (if you haven't previously did) and so you are able to access you view class members.
You can do this also by creating thread and one handler that will be used to update your UI components. Remember that if you use threads you'll need to lock/unlock your database object because of the thread safety(if any other thread is accessing the database for any reason). Read more about thread safety of dbs.
I was doing some searching myself, and I came across this read, its rather long but looks extremely helpful, with lots of code examples. (I bookmarked it for myself).
Threads, Async, and Handlers O MY!
But some form of threading is the ticket.
From Android dev.
(My favorite code snippet)
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
//Do Work here
}
}).start();
}