I am trying to call a new activity class has below from Async class that i used for webservice,i am not able to remove the error coming on intent prompting to remove if loop,i am new to android i am not sure if i am doing correct.I just need to call a activity class after webservice call passing the output data to activity.
private class AsyncCallWS extends AsyncTask < String, Void, Void > {
#Override
protected Void doInBackground(String...params) {
//Invoke webservice
vaildUserId = WebService.invokeAuthenticateUserWS(loginUserName, loginPassword, "AuthenticateUser");
if (vaildUserId >= 0) {
System.out.println("userId---" + vaildUserId);
List < GetReminder > reminderList = WebService.invokeHelloWorldWS("GetReminder");
if (reminderList.size() > 0) {
for (int i = 0; i < reminderList.size(); i++) {
System.out.println("displayText---" + reminderList.get(i).getRemMessage() + "ff" + reminderList.size()); * * reminderIntent = new Intent(this, ReminderActivity.class); * * startActivity(reminderIntent);
}
} else {
//no invoice found
}
}
return null;
}
you may look into this:
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
code:
protected void onPostExecute(Void result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
***************Passing the data:************
Intent reminderIntent=new Intent(this, ReminderActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("data", sharedBookingObject);
reminderIntent.putExtras(bundle);
startActivity(reminderIntent);
finish();
}
Retrieving the data:
Bundle bundle = getIntent().getExtras();
sharedBookingObject = bundle.getParcelable("data");
finish() and calling Intent cannot occur outside of an activity. Use this intent in the onPostExecute() of the 'AsyncTask'
You can't update UI from background thread.
You should move your code to start Activity from doInBackground() to onPostExecute()
Use runOnUiThread method to call startActivity in main (UI) thread as this:
runOnUiThread(new Runnable() {
#Override
public void run() {
startActivity(reminderIntent);
}
});
Related
In my Main Activity Having two different AsyncTask Running in background.
after AsyncTask its start the new Activity.
this Working fine
Main Activity---->>>>New Activity
Problem:
but my Problem is Without Completing the two AsyncTasks, it Moving to New Activity
Both Task must be complete then only go to New Activity.
Help me how to Solve this.
AsyncCallWSfor1 task1 = new AsyncCallWSfor1();
// Call execute
task1.execute();
AsyncCallWSfor2 task2 = new AsyncCallWSfor2();
// Call execute
task2.execute();
Toast.makeText(sign_in.this, "Login Successfull",Toast.LENGTH_LONG).show();
Intent intent = new Intent(MainActivivty.this,NewActvity.class);
startActivity(intent);
finish();
It will definately solve your problem do something like this
//create variable for your activity or fragment
Boolean isTask1Completed=false,isTask2Completed=false;
//on post execute of task 1
isTask1Completed = true;
if(isTask1Completed&&isTask2Completed){
//start activity here
}
//on post execute of task 2
isTask2Completed = true;
if(isTask1Completed&&isTask2Completed){
//start activity here
}
Use some simple checkers
boolean first = false;
boolean second = false;
and
AsyncTask1
onPostExecute() {
first = true;
if (first && second) startActivity();
}
AsyncTask2
onPostExecute() {
second = true;
if (first && second) startActivity();
}
Why can't you try both method using one Asynchronous Task
private class MyTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... url) {
String result="";
if(url.equals("m1"))
{
<!--Method one-->
result="first";
}else
{
<!--Method Two-->
result="second";
}
return result;
}
#Override
protected void onPostExecute(String result) {
if(result.equals("second")
{
<!--Start activity-->
}else
{
<!--Call Asynchronous task with second method-->
}
}
}
You need to add below code
Toast.makeText(sign_in.this, "Login Successfull",Toast.LENGTH_LONG).show();
Intent intent = new Intent(MainActivivty.this,NewActvity.class);
startActivity(intent);
finish()
in your..
AsyncCallWSfor2 task2 = new AsyncCallWSfor2();
post method it will run fine....
I would suggest working with Callbacks.
You start your (i think) API Client or something and run a query.
When it starts, it will run the request in a new Thread and once it has finished loading, it will call back to the activity which has startet the request.
On this way you can be sure, tasks will be done one after another.
Activity -> new ApiClient() -> execute(url, parameters) -> new Thread() -> run Query -> Call ApiClientCallback -> Activity receives response -> do whatever is necessary
Have a look here: http://www.techotopia.com/index.php/A_Basic_Overview_of_Android_Threads_and_Thread_handlers
Asynctasks are executed serially. You should put it on postExecute of the second task.
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.
Take a boolean variable
boolean firstCompleted=false;
In onPostExecute(-) of AsyncCallWSfor1 make it as true
firstCompleted=true;
And in onPostExecute(-) of AsyncCallWSfor2 start new Activity
if(firstCompleted){
Toast.makeText(sign_in.this, "Login Successfull",Toast.LENGTH_LONG).show();
Intent intent = new Intent(MainActivivty.this,NewActvity.class);
startActivity(intent);
}
Hope this will helps you.
I am running a task in back ground, and returning a result out of it.The result is coming null as its returned before the async task completes.how can i resolve it
public Result CallServer(String zObjectNameP, String zMethodNameP, String QueryStringP)
{
aResultM=new Result();
MainAynscTask asyncTask = new MainAynscTask();
try
{
asyncTask.execute(zObjectNameP,zMethodNameP,QueryStringP);
}
catch(Exception ex)
{
}
return aResultM;
}
The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
Use a Handler
In your activity
mHandler = new Handler() {
#Override public void handleMessage(Message msg) {
String s=(String)msg.obj;
tv.setText("Result = "+s);
}
};
In your onPostexecute
protected void onPostExecute(String result)//result returned in doInbackground
{
pd.dismiss();
if(result != null)
{
Message msg=new Message();
msg.obj=result.toString();
mHandler.sendMessage(msg);
}
}
I created an async task to call my server to get data from DB.
I need to process the result returned from http server call.
From my activity i calling the async task in many places. so i cant use member variable to access the result. is there any way to do?
public Result CallServer(String params)
{
try
{
new MainAynscTask().execute(params);
}
catch(Exception ex)
{
ex.printStackTrace();
}
return aResultM;//Need to get back the result
}
private class MainAynscTask extends AsyncTask<String, Void, Result> {
#Override
protected Result doInBackground(String... ParamsP) {
//calling server codes
return aResultL;
}
#Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
//how i will pass this result where i called this task?
}
Try to call the get() method of AsyncTask after you call the execute() method. This works for me
http://developer.android.com/reference/android/os/AsyncTask.html#get()
public Result CallServer(String params)
{
try
{
MainAynscTask task = new MainAynscTask();
task.execute(params);
Result aResultM = task.get(); //Add this
}
catch(Exception ex)
{
ex.printStackTrace();
}
return aResultM;//Need to get back the result
}
...
...
There are two ways i can suggest -
onPostExecute(Result) in AsyncTask. See http://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute(Result)
Send a broadcast with the result as an extra.
AsyncTask is an asynchronous task so it does NOT make sense to return the result to the caller. Rather handle the result in onPostExecute() like setting the value to TextView etc. Or send a broadcast so that some other listener can handle the result.
Here's how I got around this:
1) Create an interface class that defines a signature for a method to execute on completion:
public interface AsyncIfc {
public void onComplete();
}
2) Set a property on your AsyncTask class to hold the delegate method:
public AsyncIfc completionCode;
3) Trigger the delegate from onPostExecute() in the AsyncTask:
completionCode.onComplete();
4) From your calling logic, set the delegate property to an anonymous method:
task.completionCode = new AsyncIfc() {
#Override
public void onComplete() {
// Any logic you want to happen after execution
}
};
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
Use a handler
In your activity
Handler mHandler = new Handler() {
#Override public void handleMessage(Message msg) {
String s=(String)msg.obj;
tv.setText(s);
}
};
//result is soap object in this case.
protected void onPostExecute(SoapObject result) {
pd.dismiss();
if(result != null) {
Message msg=new Message();
msg.obj=result.getProperty(0).toString();
mHandler.sendMessage(msg);
}
when i press my login button there is a webservice call , at the time of web service call i have to display a progress dialog, and after receiving webservice return an intent to next page... but it always diplays a blank page when intent is called also progress dialog is not showing
if(Utility.isNetworkAvailable(currActivity)){
// Utility.showProgressDialog(currActivity);
new Thread() {
#Override
public void run() {
currActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(Login.this, Listviewer.class);
startActivity(intent);
tempSplashTread = new Thread() { // Thread for showing wait cursor
#Override
public void run() {
currActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
myProgressDialog = new ProgressDialog(InfraSignPdfList.this);
myProgressDialog.setMessage("Loading... ");
myProgressDialog.show();
}
});
}
};
tempSplashTread.start();
finish();
}
});
}
}.start();
}else {
Utility.noNetworkDialog(currActivity);
}
It's a bad idea to put a progress dialog between launching apps. You need to implement the progress dialog in the one that does the download and then display the next Activity after the downloaded data has been passed to the new activity.
Follow below steps:
1.After Login Button start server call to get data from server till then display progressDialog on current activity.
2.After the data has been downloaded start the next Activity by passing the necessary data to it.
You should do this with the help of AsyncTask (an intelligent backround thread) and ProgressDialog
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.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called begin, doInBackground, processProgress and end.
The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread immediately after the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
Threading rules
There are a few threading rules that must be followed for this class to work properly:
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
Example code
What the adapter does in this example is not important, more important to understand that you need to use AsyncTask to display a dialog for the progress.
private class PrepareAdapter1 extends AsyncTask<Void,Void,ContactsListCursorAdapter > {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(viewContacts.this);
dialog.setMessage(getString(R.string.please_wait_while_loading));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
/* (non-Javadoc)
* #see android.os.AsyncTask#doInBackground(Params[])
*/
#Override
protected ContactsListCursorAdapter doInBackground(Void... params) {
cur1 = objItem.getContacts();
startManagingCursor(cur1);
adapter1 = new ContactsListCursorAdapter (viewContacts.this,
R.layout.contact_for_listitem, cur1, new String[] {}, new int[] {});
return adapter1;
}
protected void onPostExecute(ContactsListCursorAdapter result) {
list.setAdapter(result);
dialog.dismiss();
}
}
This question already has answers here:
Android SDK AsyncTask doInBackground not running (subclass)
(9 answers)
Closed 9 years ago.
I'm having a problem with the AsyncTask class. It seems like my task stops working after creating 4 or 5 tasks.
Im having 2 activities. MainActivity which only holds a button that starts a second activity called ImageActivity.
ImageActivity is very simple. it got an onCreate that sets the layout, and then it starts a new AsyncTask that loads an image from the internet. This works fine the first few times. But than it suddenly stops working. The onPreExecute method is run every time, but not the doInBackground method. I have tried to simplify the doInBackground with a sleeping loop, and the same thing happens. I cant understand this behavour since the asynctask is both canceled and set to null in the onDestroy method. So every time i start a new ImageActivity, i also create a fresh AsyncTask.
I recreate the ImageActivity and the task by hitting the back button, and than clicking the button on the MainActivity.
Any ideas anyone? I'm really struggling with this one.
UPDATE: Code that starts the ImageActivity (inside a button onClickListener)
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.setClassName(this, ImageActivity.class.getName());
startActivity(intent);
The code above starts this activity
public class ImageActivity extends Activity {
private AsyncTask<Void, Void, Void> task;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.main);
task = new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute()
{
Log.d(TAG, "onPreExecute()");
}
#Override
protected Void doInBackground(Void... params)
{
Log.d(TAG, "doInBackground() -- Here is the download");
// downloadBitmap("http://mydomain.com/image.jpg")
return null;
}
#Override
protected void onPostExecute(Void res)
{
Log.d(TAG, "onPostExecute()");
if(isCancelled()){
return;
}
}
}.execute();
}
#Override
protected void onDestroy()
{
super.onDestroy();
task.cancel(true);
}
}
UPDATE:
I have tested using a combination of traditional Threads and runOnUiThread method, and it seems to work better. Now the thread runs every time.
Removing the AsyncTask and using a traditional Thread instead of combining it with runOnUiThread seems to work. But I still have not found the reason why the AsyncTask is so "unstable".
Here is the code that works for me:
public class ImageActivity extends Activity {
private Thread worker;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.main);
worker = new Thread(new Runnable(){
private void updateUI(final List<Object> list)
{
if(worker.isInterrupted()){
return;
}
runOnUiThread(new Runnable(){
#Override
public void run()
{
// Update view and remove loading spinner etc...
}
});
}
private List<Object> download()
{
// Simulate download
SystemClock.sleep(1000);
return new ArrayList<Object>();
}
#Override
public void run()
{
Log.d(TAG, "Thread run()");
updateUI(download());
}
});
worker.start(); }
#Override
protected void onDestroy()
{
super.onDestroy();
worker.interrupt();
}
}
I ran into similar problem. You can't have multiple Asynctasks running in parallel up until SDK 11. Check here for more info
I just ran into this problem as well. If you use AsyncTask.execute, your task is run on a serial queue (from the Android 4.3 source):
When first introduced, AsyncTasks were executed serially on a single
background thread. Starting with DONUT, this was changed to a pool of
threads allowing multiple tasks to operate in parallel. Starting with
HONEYCOMB, tasks are executed on a single thread to avoid common
application errors caused by parallel execution.
This is consistent with behavior that I saw. I had an AsyncTask popped up a dialog in doInBackground and blocked until the dialog was closed. The dialog needed its own AsyncTask to complete. The dialog's AsyncTask.doInBackground method never executed because the original AsyncTask was still blocked.
The solution is to execute the second AsyncTask in a separate Executor.
Use traceview to investigate -- or obtain a thread dump. My guess is that one of your AsyncTask threads are hanging on downloading.
AsyncTask has a small thread pool, so if one of your tasks hangs, it could end up blocking your thread pool.
Here's a quick test you can run -- on 4.3, I see that I have only 5 concurrent threads I can run. When one thread exits, other threads start up.
private void testAsyncTasks() {
for (int i = 1; i <= 10; i++) {
final int tid = i;
new AsyncTask<Integer, Void, Void>() {
protected void onPreExecute() {
Log.d("ASYNCTASK", "Pre execute for task : " + tid);
};
#Override
protected Void doInBackground(Integer... args) {
int taskid = args[0];
long started = SystemClock.elapsedRealtime();
Log.d("ASYNCTASK", "Executing task: " + taskid + " at " + started);
for (int j = 1; j <= 20; j++) {
Log.d("ASYNCTASK", " task " + taskid + ", time=" + (SystemClock.elapsedRealtime() - started));
SystemClock.sleep(1000);
}
return null;
}
protected void onPostExecute(Void result) {
Log.d("ASYNCTASK", "Post execute for task : " + tid);
};
}.execute(i);
}
}
You shouldn't have to worry about housekeeping thread in Android as it is managed by the system.
Please also post the image download method. Have you also tried to not cancel the thread in the onDestroy() method? How are you returning the the image to your UI thread?
The problem I believe is with the heavy image download task. Even if you cancel the async task the image download will continue to execute and the async task does not finish until the download is complete. You might want to check the isCancelled() method on AyncTask while the download is going on and kill the download if the task is cancelled.
For reference, heres the documentation on cancel() method :
Attempts to cancel execution of this task. This attempt will fail if the task has already completed, already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
Calling this method will result in onCancelled(Object) being invoked on the UI thread after doInBackground(Object[]) returns. Calling this method guarantees that onPostExecute(Object) is never invoked. After invoking this method, you should check the value returned by isCancelled() periodically from doInBackground(Object[]) to finish the task as early as possible.
I had this too, no real reason for not starting. I've noticed that after restarting adb it worked again. Not sure why this is, but it did work for me