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
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 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);
}
}
}
I try to start two AsyncTask in MainActivity's onCreate function
My task is to start them same time but I look that Authorization process start after Directory Scan process has completed. Why?
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
task1 = new MyTask1();
task1.execute(); // Asynch ???
task2 = new MyTask2();
task2.execute(); // Asynch ???
class MyTask1 extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
// Disk scan process with using some functions from MainActivity
DiskScanProcess();
} catch (InterruptedException e) {
}
return null;
}
}
class MyTask2 extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
// Authorizatin process with using some functions from MainActivity
AuthorizationProcess();
} catch (InterruptedException e) {
}
return null;
}
}
}
The documentation for AsyncTask, in the section titled "Order of execution", explains that "Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution". If you want multiple tasks to execute in parallel, invoke them with executeOnExecutor().
I made an application for Android that originally targeted a lower version (2.3). After I got my proof-of-concept working, I tried to get it to work on Android 4. That's when I got the NetworkOnMainThread exception.
After doing some research, I quickly found the AsyncTask, which sounded awesome. The problem is, I'm having a hard time wrapping my mind around it. For instance, here's my original code:
public void Refresh(Context c)
{
SummaryModel model = MobileController.FetchSummary(c);
TextView txtCurrentWeight = (TextView)findViewById(R.id.txtCurrentWeight);
TextView txtWeightChange = (TextView)findViewById(R.id.txtWeightChange);
TextView txtAvgPerWeek = (TextView)findViewById(R.id.txtAvgPerWeek);
if(model.ErrorMessage == "")
{
txtCurrentWeight.setText(model.CurrentWeight);
txtWeightChange.setText(model.WeightChange);
txtAvgPerWeek.setText(model.Average);
}
else
{
Toast.makeText(c, model.ErrorMessage, Toast.LENGTH_LONG).show();
txtCurrentWeight.setText("");
txtWeightChange.setText("");
txtAvgPerWeek.setText("");
}
}
I created an AsychTask like this:
public class WebMethodTask extends AsyncTask<Object, Integer, Object> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
SummaryModel model = (SummaryModel)result;
// Can't seem to access UI items here??
}
#Override
protected Object doInBackground(Object... params) {
Context c = (Context)params[0];
return MobileController.FetchSummary(c);
}
}
How do I access the UI items from the onPostExecute method? Or, do I have the wrong idea on how to use AsyncTask?
Thanks!
You should be able to accessUI where you put your comments (in the postExecute method)
Additionally, I would suggest to use more specialized class with for AsyncTask, so that your code looks better :
public class WebMethodTask extends AsyncTask<Object, Integer, SummaryModel> {
private Activity source;
public WebMethodTask(Activity activity) {
this.source=activity;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(SummaryModel model) {
super.onPostExecute(model );
TextView txtCurrentWeight = (TextView)source.findViewById(R.id.txtCurrentWeight);
TextView txtWeightChange = (TextView)source.findViewById(R.id.txtWeightChange);
TextView txtAvgPerWeek = (TextView)source.findViewById(R.id.txtAvgPerWeek);
if(model.ErrorMessage.length()==0)
{
txtCurrentWeight.setText(model.CurrentWeight);
txtWeightChange.setText(model.WeightChange);
txtAvgPerWeek.setText(model.Average);
}
else
{
Toast.makeText(c, model.ErrorMessage, Toast.LENGTH_LONG).show();
txtCurrentWeight.setText("");
txtWeightChange.setText("");
txtAvgPerWeek.setText("");
}
}
#Override
protected SummaryModel doInBackground(Context ... params) {
Context c = params[0];
return MobileController.FetchSummary(c);
}
}
Edit : Added a reference to your activity, to take your last comment into account.
However, if you acynctask can be long, it's maybe not a very good idea to keep a reference on an activity.
It would be a better design to create a listenerclass that will accept some displayModel(CummaryModel) method, and whose responsability is to cal the setText methods if the activity has not been paused / stopped in the meanwhile...
Fill the ui items with the loaded model data in the WebMethodTask#onPostExecute method.
You need a reference to your UI controls. When passing references to your UI controls to the ASyncTask you will create problems.
Assume the following scenario:
show activity (activity instance 1)
call async task with te activity as reference.
rotate your device (by default a device rotation will create a new activity) -> (activity instance 2)
when the sync task is finished, activity instance 1 is used to display the results. However the activity no longer exists causing exceptions.
The conclusion is that the ASyncTask should not be used for network activity related background tasks.
Fortunately there is a solution: RoboSpice.
RoboSpice uses another approach. Look at https://github.com/octo-online/robospice/wiki/Understand-the-basics-of-RoboSpice-in-30-seconds for a good explanation.
More information: https://github.com/octo-online/robospice
create an inner class in refresh method as
enter code herepublic void Refresh(Context c)
{
SummaryModel model = MobileController.FetchSummary(c);
TextView txtCurrentWeight = (TextView)findViewById(R.id.txtCurrentWeight);
TextView txtWeightChange = (TextView)findViewById(R.id.txtWeightChange);
TextView txtAvgPerWeek = (TextView)findViewById(R.id.txtAvgPerWeek);
if(model.ErrorMessage == "")
{
txtCurrentWeight.setText(model.CurrentWeight);
txtWeightChange.setText(model.WeightChange);
txtAvgPerWeek.setText(model.Average);
}
else
{
Toast.makeText(c, model.ErrorMessage, Toast.LENGTH_LONG).show();
txtCurrentWeight.setText("");
txtWeightChange.setText("");
txtAvgPerWeek.setText("");
}
class WebMethodTask extends AsyncTask<Object, Integer, Object> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
SummaryModel model = (SummaryModel)result;
// Can't seem to access UI items here??
}
#Override
protected Object doInBackground(Object... params) {
Context c = (Context)params[0];
return MobileController.FetchSummary(c);
}
}
}
Hi I'm making Login page that access MySQL database. But my Activity always runs the code that check fail/success before it finishes the AsyncTask.
I tried using asynctask.get() method, but it just freeze my UI and doesn't work.
I tried this answer that said I should call the result-checker method inside onPostExecute().
But since I need to change the TextView to show success/failed, it results in NullPointerException because I instantiate the TextView inside onCreate().
I can't move the TextView instantiation into constructor because it will return NullPointerException unable to instantiate activity ComponentInfo.
Login.java
public class Login extends Activity{
//declare global Views here
protected void onCreate(Bundle bundle){
//Setup views
}
protected void onClick(View v){
//Setup necessary variables
AsyncClass async = new AsyncClass(this);
async.execute(username, password);
}
public void checkSuccess(boolean success){
if(success)
textView1.setText("Success");
else
textView1.setText("Failed");
}
}
AsyncClass.java
public class AsyncClass extends AsyncTask<String, String, JSONObject>{
protected JSONObject doInBackground(String... params){
//access database
}
protected void onPostExecute(JSONObject json){
//read the json result
Login login = new Login();
login.checkSuccess(true);
}
}
Any solution? Thanks
How about making AsyncTask as your inner class?
So your code should look something like below.
public class Login extends Activity {
//declare global Views here
protected void onCreate(Bundle bundle) {
//Setup views
}
protected void onClick(View v) {
new AsyncClass().execute(username, password);
}
public void checkSuccess(boolean success) {
if (success) textView1.setText("Success");
else textView1.setText("Failed");
}
class AsyncClass extends AsyncTask < String, String, JSONObject > {
protected JSONObject doInBackground(String...params) {
//access database
}
protected void onPostExecute(JSONObject json) {
checkSuccess(true / false);
}
}
}
try this
protected void onPostExecute(JSONObject json){
//read the json result
Login login = (Login)context; // object that you pass to task constructor
login.checkSuccess(true);
}
Also you can add progress dialog to your task to indicate some job execution
public class BaseTask<T> extends AsyncTask<Object, Void, T> {
public Context context;
public ProgressDialog dialog;
public BaseTask(Context context) {
this.context = context;
this.dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
this.dialog.setMessage(context.getResources().getString(R.string.loading));
this.dialog.show();
}
#Override
protected T doInBackground(Object... objects) {
//....
return something;
}
#Override
protected void onPostExecute(T result) {
if (dialog != null && dialog.isShowing())
dialog.dismiss();
// do something
}
}
You cannot edit the UI from the async task thread. In order to make updates to the UI thread, use the onProgressUpdate() method. This method is part of your AsyncTask class, is actually executed in the main UI Thread (I hope you use the async task as a nested class btw, since it is declared public I guess your not. You should change that). The onProgressUpdate() Method is called by the OS itself if you call publishProgress(...) inside your Async task.
A small sample:
protected JSONObject doInBackground(String... params){
publishProgress("test");
}
/**
* This method is part of the Async Task
*/
protected void onProgressUpdate(String... progress) {
login.checkSuccess(true);
}
I would use it this way, just override your onPostExecute where you need it or create a own interface
//create a object f your asyncclass and
//override the onPostExecute where you need it
mInfo = new ASYNCCLASS({
#Override
public void onPostExecute(Object result){
//doSomething something with your views!
}
}).execute();
Waiting is not the answer, because you do not know how long your Asynctask will take to end.
Code above is not tested, just pseudoce, but it should show what i mean.
Do not have my IDE round here, so if anybody would correct the brackets if neccessary would be great!
Greetz