I have an Async task:
private class UpdateApp extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String result = "";
try{
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(),0);
curVersionCode = packageInfo.versionCode;
} catch (Exception Ignored) {
}
result = check(curVersionCode);
return result;
}
...
#Override
protected void onPostExecute(final String success){
if (success != "a") this.cancel(true); //Here's the confusion
switch (success){
case "z":
new AlertDialog.Builder(mContext).setMessage("0").setCancelable(true).show();
break;
case "a":
new AlertDialog.Builder(mContext).setMessage("1").setCancelable(true).show();
break;
default:new AlertDialog.Builder(mContext).setMessage("default").setCancelable(true).show();
break;
}
}
I want to stop the Asynctask if success is !=a. How to achieve that?
It is possible to let it continue and switch through only if success == a and break otherwise. What will be best - let it continue or cancel the task midway?
If the code in onPostExecute() runs than doInBackground is finished().
So the AsyncTask has stopped then.
It does not have to be cancelled anymore.
Does not make sense.
One can use OBJECT_OF_ASYNK_TASK.cancel();
In Android Studio explanation of this method is give check that for more information
class Temp extends AsyncTask<Void,Void,Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
private void runTemp(){
Temp temp = new Temp();
temp.execute();
temp.cancel(true);
}
Related
Here is my main Activity in OnCreate:
mUnityPlayer = new UnityPlayer(this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
new SimuDownloadTask(this).execute();
The following code is the source code of SimuDownloadTask:
public class SimuDownloadTask extends AsyncTask<Void, Integer, Boolean> {
private ProgressDialog progressDialog;
private int count=0;
private Context mainActivityContext;
public SimuDownloadTask(Context context) {
mainActivityContext=context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog=new ProgressDialog(mainActivityContext,R.style.XMNewDialog);
progressDialog.show();
}
#Override
protected Boolean doInBackground(Void... arg0) {
while(true)
{
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int downloadPercent=doDownload();
publishProgress(downloadPercent);
if(downloadPercent>=500)
break;
}
return true;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setMessage("current progress:"+values[0]+"%");
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialog.dismiss();
if(result)
{
Toast.makeText(mainActivityContext, "success", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(mainActivityContext, "fail", Toast.LENGTH_SHORT).show();
}
}
private int doDownload()
{
count+=1;
return count;
}
}
Here is the problem. When I start the app, the progressbar blocks the UI thread.
After the progressbar finished, the Unity starts.
When I replace the SimuDownloadTask in OnCreate with the following code:
new Thread(){
#Override
public void run() {
super.run();
Looper.prepare();
progressDialog=new ProgressDialog(UnityPlayerActivity.this,R.style.XMNewDialog);
progressDialog.setTitle("test");
progressDialog.setCancelable(true);
progressDialog.show();
Looper.loop();
}
}.start();
The unity thread is running properly(not blocked by the progressbar). So I think the problem is not relevant to Unity.
I have already checked the relevant links such as:
Asynctask from non ui thread
But still can't figure out the issues.
Any clues will be helpful.
Instead of using an AsyncTask you may use a worker thread for the counter logic and a handler to update the progress bar.
See the updated answer in this link
I am calling a web service using AsyncTask in a android app and I can not figure out how to wait until the onPostExecute has finished:
//Call Async Web Service here
AsyncCallWS task = new AsyncCallWS();
task.execute();
//Need to wait to fill this in ** Its not waiting.
String sCall = rslt;
String[] aCall = sCall.split("//|");
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
#Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
GetURL();
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
try{
//Results HERE
rslt = resultString.toString();
}
catch(Exception ex)
{rslt = ex.toString()+ "|" + ex.toString();}
}
}
I'm not clear on what you can't/don't want to do from onPostExecute but you can use a callback if you are wanting to execute something that's not coupled to the task (so that you can run the task from anywhere)
private class OnFinishedListener {
void onFinished(String rslt);
}
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
private OnFinishedListener mAfter;
public AsyncCallWS(OnFinishedListener after) {
mAfter = after;
}
...
#Override
protected void onPostExecute(Void result) {
....
if (mAfter != null) {
//you didnt illustrate what resultString is, you might
//want this to be the returned value from doInBackground
mAfter.onFinished(resultString.toString());
}
}
}
Usage
new AsyncCallWS(new OnFinishedListener {
public void onFinished(String rslt) {
//for example
String sCall = rslt;
String[] aCall = sCall.split("//|");
}
}).execute();
You can use Tasks.await(task) in a background thread. Do not use this in UI thread. You can also set timeout for your task Tasks.await(task, 500, TimeUnit.MILLISECONDS);
Use the getStatus() method.
while (task.getStatus() != Status.FINISHED);
A better way to do this would be to call split() inside the onPostExecute() method, since onPostExecute() runs on the UI thread anyway and the while() call would block the current thread it's running in.
I am new to android programming. I am developing a web crawler for which i am using a Async Task and it is working well.In order to keep user informed,i am using progress dialog. My problem is,if i use a Progress Dialog my program takes more time to execute and when i won`t use the progress dialog,it executes faster.
Done Work
OnCreate Method
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results);
Intent intent = getIntent();
s1 = intent.getStringExtra("Number1");
s2 = intent.getStringExtra("Number2");
s3=intent.getIntExtra("selectedItem",0);
HttpAsyncTask asyncTask = new HttpAsyncTask();
asyncTask.execute();
}catch (Exception e)
{
messageBox("Exception",e.getMessage());
}
}
Async Task Class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private ProgressDialog dialog;
#Override
protected void onPreExecute()
{
dialog = new ProgressDialog(Results.this);
dialog.setIndeterminate(true);
dialog.setMessage("Please Wait");
dialog.setCancelable(true);
dialog.show();
super.onPreExecute();
}
#Override
protected List<String> doInBackground(List<String>... urls) {
//android.os.Debug.waitForDebugger();
// spinner.setVisibility(View.VISIBLE);
List<String>resultList=new ArrayList<String>();
try
{
if(isCancelled())
return resultList;
resultList=WebCrawlerClass.GetPost(s1,s2,s3);
}catch (Exception e)
{
messageBoxs("Error", e.getMessage());
}
return resultList;
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(List<String> result)
{
if(dialog.isShowing())
{
dialog.dismiss();
}
if(s3 == 2)
{
docListAdapter=new ListViewData(Results.this,result);
}
else {
docListAdapter = new NameNumListData(Results.this, result);
}
docList=(ListView)findViewById(R.id.listView2);
docList.setAdapter(docListAdapter);
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
super.onCancelled();
this.cancel(true);
}
}
Am I missing something? Need help..
Thanks and Regards,
Abhinav
In you activity
// Start the progress dialog
..
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// dismiss the progress dialog
}
};
HttpAsyncTask asyncTask = new HttpAsyncTask(handler);
asyncTask.execute();
In your asynctask class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private Handler handler = null;
public HttpAsyncTask (Handler handler) {
this.handler = handler;
}
protected Void doInBackground(Void... params) {
//Perform your task
// When you know that task is finished , fire following code
if (null != handler) {
Message message = handler.obtainMessage();
message.obj = Any data you want to sent to the activity
message.what = 1 ; ( Optional )
handler.sendMessage(message);
}
}
Thus when sendMessage function is called from doInbackground.. your handleMessage in your activity will get triggered and then you should dismiss the progress dialog
Hope this will improve the performance issue what you are facing
Remove super.onPreExecute(); in onPreExecute() method and check .It might Help
I am developing an feedback kind of application, when I click the "submitnow" button I am getting the following error
Activity has leaked window
com.android.internal.policy.impl.PhoneWindow$DecorView#46029dd0
Following is my code, please help me out.
public class SignOut_Activity extends SherlockActivity implements
OnClickListener {
Button btnSubmitNow, btnSubmitLater;
ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setContentView(R.layout.signout);
((TextView) findViewById(R.id.tvSubTitle))
.setText(StoresListAdapter.StoreName);
btnSubmitNow = (Button) findViewById(R.id.btnSubmitNow);
btnSubmitLater = (Button) findViewById(R.id.btnSubmitLater);
btnSubmitNow.setOnClickListener(this);
btnSubmitLater.setOnClickListener(this);
progressDialog = new ProgressDialog(SignOut_Activity.this);
progressDialog.setMessage("Uploading data, please wait...");
}
#Override
public boolean onOptionsItemSelected(
com.actionbarsherlock.view.MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; finish activity to go home
finish();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onResume() {
super.onResume();
// Set title
getSupportActionBar().setTitle("Sign Out");
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSubmitNow:
// Submit now
// Sample upload image
UploadImage.uploadImage("testimage");
new AsyncTask<Void, Void, Void>() {
// called before execution // main/UI thread
protected void onPreExecute() {
progressDialog.show();
};
#Override
protected Void doInBackground(Void... params) {
// Submit the store data
StoreData.postData(StoreList_Activity.storesList
.get(StoresListAdapter.Position));
return null;
}
// on store data uploaded // main/UI thread
protected void onPostExecute(Void result) {
progressDialog.dismiss();
setSignOut();
StoreList_Activity.storesList
.get(StoresListAdapter.Position).isSubmitted = true;
SignOut_Activity.this.finish();
};
}.execute();
break;
case R.id.btnSubmitLater:
// Submit later
setSignOut();
StoreList_Activity.storesList.get(StoresListAdapter.Position).isSubmitLater = true;
VisitOps_Activity.isSubmitLater = true;
SignOut_Activity.this.finish();
break;
default:
break;
}
}
#SuppressLint("SimpleDateFormat")
private void setSignOut() {
VisitOp visitOp10 = new VisitOp();
visitOp10.setName("Sign Out");
visitOp10.setStatus("");
SampleData.visitOpsList.add(visitOp10);
if (VisitOps_Activity.VisitOps.SignOut == null)
VisitOps_Activity.VisitOps.SignOut = new SignOut();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentDateandTime = sdf.format(new Date());
VisitOps_Activity.VisitOps.SignOut.SignOutTime = "Out: "
+ currentDateandTime;
}
}
Leak comes because you are keeping reference of activity after it destroyed also so use
if(progressDialog !=null)
{
progressDialog = null;
}
progressDialog = new ProgressDialog(this.getApplicationContext());
progressDialog.setMessage("Uploading data, please wait...");
OR
use this it will help
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSubmitNow:
// Submit now
// Sample upload image
UploadImage.uploadImage("testimage");
new AsyncTask<Void, Void, Void>() {
// called before execution // main/UI thread
protected void onPreExecute() {
progressDialog = new ProgressDialog(SignOut_Activity.this);
progressDialog.setMessage("Uploading data, please wait...");
progressDialog.show();
};
#Override
protected Void doInBackground(Void... params) {
// Submit the store data
StoreData.postData(StoreList_Activity.storesList
.get(StoresListAdapter.Position));
return null;
}
// on store data uploaded // main/UI thread
protected void onPostExecute(Void result) {
progressDialog.dismiss();
setSignOut();
StoreList_Activity.storesList
.get(StoresListAdapter.Position).isSubmitted = true;
SignOut_Activity.this.finish();
};
}.execute();
Why this Error...?
this error happen when you keep reference of unused activity
Solution
remove reference of progress bar , dialog .....etc after use it .
by dismiss them or make them equal null
you can approach this when no longer need of it
Recommended put it in onStop
#Override
protected void onStop() {
super.onStop();
if(_dialog.isShowing()){
_dialog.dismiss();
}
if(_dialog != null){
_dialog = null;
}
}
Dismiss the dialog after its use, it won't let your application crash.
dialog.dismiss();
use that code progressDialog.dismiss();
Make sure you dismiss() the dialog, after dialog use and before any next background process to be initiated.
How would I call this function in asynctask?
void somefunc()
{
tr1 = (TableRow) new TableRow(this);
//error
txt1=new TextView(this);
txt9.setText(strinarr[0]);
tr1.addView(txt1);
tl.addView(tr1,new TableLayout.LayoutParams(layoutParams));
}
class SaveAdDetail extends AsyncTask<Void, String, Void>
{
#Override
public void onPreExecute()
{
super.onPreExecute();
Progdialog = ProgressDialog.show(demotable.this, "", "Please Wait...", true);
Progdialog.show();
}
#Override
public Void doInBackground(Void... unused)
{
try
{somefunc();}
catch (Exception e)
{strdata="Error";}
return null;
}
#Override
public void onPostExecute(Void unused)
{
Progdialog.dismiss();
if(strdata.equals("Error"))
{Toast(strdata);}
else
{
Toast("asdasdasd");
}
}
}
You have a choice : use handlers or call directly. In both cases you should pass a reference to the constructor of AsyncTask. onPostExecute() is called on the UI thread, so you can call the method directly on the reference of your activity.
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.TASK_FINISHED:
somefunc();
break;
}
}
};
SaveAdDetail task = new SaveAdDetail(handler);
task.execute();
// in your SaveAdDetail:
#Override
public void onPostExecute(Void unused) {
Progdialog.dismiss();
handler.obtainMessage(Constants.TASK_FINISHED).sendToTarget();
}
I would use a Handler. Here is an example: http://developer.android.com/resources/articles/timed-ui-updates.html