I have an Android app where when I switch from Activity A back to Main Activity, then to B, then press button the code calls an AsyncTask.
OnPreExecute() is called right away but it takes about a minute before doInBackground() is called.
I use execute() to start the task. Using executeOnExecutor() has no effect.
Why is there a delay?
I have checked and do not have any other AsyncTasks running.
I am running API 19 KitKat. No choice since it must run on TC-70 using EMDK.
Any ideas on where to start looking?
public class BarcodeHandler
implements EMDKListener, DataListener, StatusListener, ScannerConnectionListener {
#Override
public void onData(ScanDataCollection scanDataCollection) {
String dataString = "test";
new AsyncDataUpdate().execute(dataString);
}
...
}
private class AsyncDataUpdate extends AsyncTask<String, Void, String>
{
#Override
protected void onPreExecute()
{
Log.d("delayTest", "DataUpdate PreExecute()");
}
#Override
protected String doInBackground(String... params) {
Log.d("delayTest", "DataUpdate doInBackground");
return params[0];
}
protected void onPostExecute(String result) {
Log.d("delayTest", "DataUpdate onPostExecute");
if (result != null) {
if (dataListener != null)
dataListener.barCodeListener(result);
}
}
}
Related
I don't know how to tell the problem.
I have two AsyncTask methods. doAreYouStanding and StartTimeout, when I'm running both in MainActivity
if StartTimeout in if I wait 10 seconds, the other method is waiting.
Why is this startTimeout thread pausing my other method?
doAreYouStanding in doInBackground works after waiting onPreExecute for 10 seconds
new doPopup().execute((Void) null);
// new StartTimeout().execute((Void) null);
private class doAreYouStanding extends AsyncTask<Object, Object, Void> {
#Override
protected void onPreExecute() {
Log.e("YHACKUP", "onPreExecute");
super.onPreExecute();
}
#Override
protected Void doInBackground(Object... objects) {
Log.e("YHACKUP", "doInBackground");
return null;
}
}
private class StartTimeout extends AsyncTask<Object, Object, Void> {
#Override
protected void onPostExecute(Void aVoid) {
if (!(ActivitySplash.this).isFinishing()) {
layout_timeout.setVisibility(View.VISIBLE);
}
super.onPostExecute(aVoid);
}
#Override
protected Void doInBackground(Object... objects) {
// try {
// Thread.sleep(10000);
// } catch (Exception e) {
// }
return null;
}
}
I'm sorry if my english is bad
By default async tasks run serially. so Intil, the first asyncTask gets completed, second asyntask will not be started. In order to run paelelly, use executeOnExecutor method
new doPopup().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
I have a method which has a async task and it is called from several different services and those services runs periodically . I want to make sure when one task is on going , no other thing can call it unless the task is finished.
public class Helper {
public static void doSomethingAsync() {
new AsyncTask<String, Void, Integer>() {
#Override
protected void onPreExecute() {
}
#Override
protected Integer doInBackground(String... strings) {
//doing something
}
#Override
protected void onPostExecute(Integer resultCode) {
}
}.execute();
}
public static void someOtherMethod(){
}
}
AsyncTask.getStatus() will give the status of the task, i.e. whether finished or not.
Declare a member variable
private static AsyncTask<String, Void, Integer> mTask;
Modify your method as,
public static void doSomethingAsync() {
if(null != mTask && mTask.getStatus() != AsyncTask.Status.FINISHED){
return; //Returning as the current task execution is not finished yet.
}
mTask = new AsyncTask<String, Void, Integer>() {
#Override
protected void onPreExecute() {
}
#Override
protected Integer doInBackground(String... strings) {
//doing something
}
#Override
protected void onPostExecute(Integer resultCode) {
}
};
mTask.execute();
}
You can try this by making your "doSomethingAsync()" as synchronized method.
public synchronized static void doSomethingAsync() {
new AsyncTask<String, Void, Integer>() {
#Override
protected void onPreExecute() {
}
#Override
protected Integer doInBackground(String... strings) {
//doing something
}
#Override
protected void onPostExecute(Integer resultCode) {
}
}.execute();
}
Note:
static synchronized method will lock the class instead of the object, and it will lock the class because the keyword static means: "class instead of instance". The keyword synchronized means that only one thread can access the method at a time.
And together they mean: "Only one can access class at one time".
Make sure all your services has access to same Mutex which can be accesses throughout your application.
Now before accessing the Async Task, do as follows
public class Mutex {
public void acquire() throws InterruptedException { }
public void release() { }
public boolean attempt(long msec) throws InterruptedException { }
}
Which then can be used as:
try {
mutex.acquire();
try {
// do something
} finally {
mutex.release();
}
} catch(InterruptedException ie) {
// ...
}
Check out more details over here
In Android we have Semaphore. For which the following will be the steps
java.util.concurrent.Semaphore semaphore=new Semaphore(1);
boolean isAvailable = semaphore.tryAcquire();
if(isAvailable){
// Access AsyncTask
}
Once all actions are done, till onPostExecute
semaphore.release();
Try using an IntentService instead as this supports queuing and runs in a background thread
You should refer Synchronization concept, it will help u.
Link
I am trying to work with Asynctask, but everytime I'm getting its status, it always returns running.
What is wrong in my code?
This is how I load my asynctask:
LongOperation LongOperation = new LongOperation(finalLink[0], download_data);
LongOperation.execute();
Toast.makeText(getApplicationContext(), LongOperation.getStatus().toString(), Toast.LENGTH_SHORT).show();
This is my asynctask:
private class LongOperation extends AsyncTask<Void, Void, Void> {
public Download_data download_data;
public String link;
public boolean loading;
public LongOperation(String link, Download_data download_data){
this.link = link;
this.download_data = download_data;
}
#Override
protected Void doInBackground(Void... params) {
download_data.download_data_from_link(link);
return null;
}
protected void onPostExecute() {
finish();
}
#Override
protected void onPreExecute() {
Toast.makeText(getApplicationContext(),"Executed.", Toast.LENGTH_LONG).show();
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Because you are checking status right after executing it:
LongOperation.execute();
Toast.makeText(getApplicationContext(), LongOperation.getStatus().toString(), Toast.LENGTH_SHORT).show();
AsyncTask runs on background thread. So right after calling execute() controls moves to display Toast. And by that time, task is still running.
You will receive finished status in onPreExecute of AsyncTask.
#Override
protected void onPostExecute(Void mVoid) {
Toast.makeText(getApplicationContext(), this.getStatus().toString(), Toast.LENGTH_SHORT).show();
finish();
}
In case you are confused about threads, do read this: Java Multithreading
The correct signature of onPostExecute() is really;
protected void onPostExecute (Result result)
Since you're not overriding the one in AsyncTask but defining another overload, it (and in its turn finish() is never called).
Fix the signature and it should complete as intended.
I have 2 AsyncTasks in two different classes but the problem is when the first is do in backgroung state the second is not executed. The first asyncTask if preformed in loop because it needs to update every 5 seconds the new data. If i stop the task (condition = flase) the second one works perfectly.
First class:
public class MapScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map_screen);
UpdateUserCords updateUC = new UpdateUserCords();
updateUC.execute();
}
class UpdateUserCords extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... params) {
while(condition)
{
//some code in loop...
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
}
Second class:
public class Groups extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_groups);
getGroups getGr = new getGroups();
getGr.execute(); //not executing, no error or crash
}
class getGroups extends AsyncTask<String, Void, String>
{
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
#Override
protected String doInBackground(String... params) {
//some code...
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
}
After Android API 11, AsyncTasks started to run on serial executor by default, that means that only one task is running at a time. To get the behavior of prior to API 11, which is running on ThreadPoolExecutor, you'll need to specify it in the code like this:
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
myTask.execute();
}
Please take a look here for more information:
http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html
Good luck!
P.S. It's not recommended to use AsyncTask for an infinite thread, AsyncTask purpose is to do a Task on the background, not to run forever, so if you want an infinite thread, I think you should create it as a Thread and not as an AsyncTask.
You asynctasks are in two different activities.
Only one activity is active at any time.
Both classes extend Activity and only one of them is running at the same time.
If you want a task to be execute longer than the lifetime of an activity, you have to wrap it into an Service
In my code I load a spinner adapter by using Async Task
In My case The ProgressDialog is Not dismissing
This is My code.
I want to show the item after adapter load and the progressDialog is to dismiss
Please Help me, Thanks
private class LoadMoreVehicals extends AsyncTask<Object, Integer, Object> {
#Override
protected void onPreExecute() {
progressBar = ProgressDialog.show(RegistrationScreen.this, "",
"Loading...");
progressBar.setIndeterminate(true);
progressBar.setIndeterminateDrawable(getResources().getDrawable(
R.anim.progressbar_handler));
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
String countryUrl = ConstantURL.COUNTRY_URL;
getCounty(countryUrl);
countrySpinner
.setAdapter(new MyCustomSpinnerAdapter(
RegistrationScreen.this,
R.layout.spinner_dropdown,
countyList));
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressBar.getProgress();
}
#Override
protected void onPostExecute(Object result) {
progressBar.dismiss();
Log.e("Im in onPostExecute", "");
super.onPostExecute(result);
}
}
While programming in Android you should remember one thing that any task which draws something on the screen should be executed on the main thread. When you set the adapter then android calls the getView() method of the adapter and draws views on the screen. So you should set the adapter in the postExecute() method instead in doInBackground() method.
Here is a small sample to clear my point:
class MyTask extends AsyncTask<Void, Void, Void> {
ProgressDialog pd = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute ( )
{
//starting the progress dialogue
pd.show();
}
#Override
protected Void doInBackground (Void... params)
{
//fetch data here
...
...
return null;
}
#Override
protected void onPostExecute (Void result)
{
//set adapter here
...
...
//dismissing the progress dialogue
pd.dismiss();
}
}
In my experience i have so many problems with async runs and UI so now always separate the stuff trying to place the "responsibilities" in each place. So i do something like this:
Create my Async class with the process i want to do and nothing that transform the UI in it
Create a function in UI thread that modify the UI when async task finish, something like OnAsyncTaskComplete(Object response)
Keep communicated the threads
public class MyActivity extends Activity {
private static MyAsyncClass backgroundTask;
private static ProgressDialog pleaseWaitDialog;
//......activity stuff.......
#Override
public void onPause()
{
super.onPause();
//Get rid of progress dialog in the event of a screen rotation or other state change. Prevents a crash.
if (pleaseWaitDialog != null)
pleaseWaitDialog.dismiss();
}
//Function to avoid lose the async thread if the app interrupts (phone rotation, incoming call, etc) RECOMENDED TO HANDLE THIS!!
//Sets the current state after app resume
#Override
public void onResume()
{
super.onResume();
//If there is a background task set it to the new activity
if ((backgroundTask != null) && (backgroundTask.getStatus() == Status.RUNNING))
{
if (pleaseWaitDialog != null)
pleaseWaitDialog.show();
backgroundTask.setActivity(this);
}
}
}
//Logic business after the web service complete here
//Do the thing that modify the UI in a function like this
private void onTaskCompleted(Object _response)
{
//For example _response can be a new adapter
MyList.setAdapter((BaseAdapter)_response);
//or can be a list to create the new adapter
MyList.setAdapter(new MyAdapter(this, (ArrayList<String>)_response));
//or can be anything you want, just try to make here the things that you need to change the UI
}
/**
* Class that handle the async task
*/
public class MyAsyncClass extends AsyncTask<Void, Void, Object>
{
//Maintain attached activity for states change propose
private MyActivity activity;
//Keep the response of the async task
private Object _response;
//Flag that keep async task completed status
private boolean completed;
//Constructor
private MyAsyncClass(MyActivity activity) {
this.activity = activity;
}
//Pre execution actions
#Override
protected void onPreExecute() {
//Start the splash screen dialog
if (pleaseWaitDialog == null)
pleaseWaitDialog= ProgressDialog.show(activity.this,
"PLEASE WAIT",
"Getting results...",
false);
}
//Execution of the async task
protected Object doInBackground(Object...params)
{
//return the thing you want or do want you want
return new ArrayList();
}
//Post execution actions
#Override
protected void onPostExecute(Object response)
{
//Set task completed and notify the activity
completed = true;
_response = response;
notifyActivityTaskCompleted();
//Close the splash screen
if (pleaseWaitDialog != null)
{
pleaseWaitDialog.dismiss();
pleaseWaitDialog = null;
}
}
//Notify activity of async task completion
private void notifyActivityTaskCompleted()
{
if ( null != activity ) {
activity.onTaskCompleted(_response);
}
}
//for maintain attached the async task to the activity in phone states changes
//Sets the current activity to the async task
public void setActivity(MyActivity activity)
{
this.activity = activity;
if ( completed ) {
notifyActivityTaskCompleted();
}
}
}
}
Hope its help you
First of all you cannot set the adapter in the doInBackground
follow this design:
private class LoadMoreVehicals extends AsyncTask<Object, Integer, Object>
{
private ArrayList<Country> countries;
#Override
protected void onPreExecute() {
progressBar = ProgressDialog.show(RegistrationScreen.this, "","Loading...");
progressBar.setIndeterminate(true);
progressBar.setIndeterminateDrawable(getResources().getDrawable(R.anim.progressbar_handler));
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
String countryUrl = ConstantURL.COUNTRY_URL;
countries = getCounty(countryUrl);
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressBar.getProgress();
}
#Override
protected void onPostExecute(Object result) {
countrySpinner.setAdapter(new MyCustomSpinnerAdapter(RegistrationScreen.this,R.layout.spinner_dropdown,countries));
progressBar.dismiss();
Log.e("Im in onPostExecute", "");
super.onPostExecute(result);
}
}