Anyone know if it possible to kill/stop AsyncTask without loop.
There was many examples with loop but the task which I should do in doInBackground() function only one function which in some cases take long time and I shall stop it for example in onPause. If it possible or I should use another task for example Futuretask.
Thanks in advance.
The code like this:
class ProcessTask extends AsyncTask<Void, Void, Boolean> {
#Override
protected Boolean doInBackground(Void... params) {
Log.i(TAG, " ---- ProcessTask -- doInBackground ----");
// Task
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Log.i(TAG, " ---- ProcessTask -- onPostExecute ----");
}
#Override
protected void onCancelled(Boolean result) {
super.onCancelled(result);
Log.i(TAG, " ---- ProcessTask -- onCancelled ----");
}
}
...
ProcessTask myTask;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
myTask = new OCRProcessTask();
myTask.cancel(false);
myTask.execute();
}
#Override
public void onPause() {
myTask.cancel(true);
}
You can cancel the AsyntTask by setting cancel(true) to the task.
new MyAsyncTask().cancel(false);
Related
I have designed an app that gets the network information and updates the UI every 5 seconds.
It is advised to do the background processes on a separate thread than the UI thread, and I did so...but I still get an error that:
"I/Choreographer﹕ Skipped 3730 frames! The application may be doing
too much work on its main thread."
Why is that?
Here's my code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wifiTextView = (TextView)findViewById(R.id.wifi_textView);
ipTextView = (TextView)findViewById(R.id.ip_val_textView);
// and so on
//Updating the UI every mInterval seconds, using a separate thread than UI thread
Thread backgroundThread = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(mInterval);
runOnUiThread(new Runnable() {
#Override
public void run() {
//Log.d(DEBUG_TAG, "run(): Background thread");
MyNetwork network = new MyNetwork(getApplicationContext()); // passing the context
updateUI(network);
}
});
}
} catch (InterruptedException e) {
wifiTextView.setText("Exception: Please Close and Restart the App");
}
}
};
backgroundThread.start();
}
In the same MainActivity class, I have this private function:
private void updateUI(MyNetwork network){
// Handles updating the textviews in the UI
//Log.d(DEBUG_TAG, "updateUI(DeepstreamNetwork)");
if (network.isConnected()){
wifiTextView.setText(R.string.wifi_is_on);
wifiTextView.setTextColor(Color.GREEN);
ipTextView.setText(network.getIpAddress());
else {
wifiTextView.setText(R.string.wifi_is_off);
wifiTextView.setTextColor(Color.RED);
ipTextView.setText("N/A");
}
}
UPDATE
So, I have updated my MainActivity class to have this MyAsyncTask method to handle background work...here's my code:
private class MyAsyncTask extends AsyncTask<Void, Void, MyNetwork> {
#Override
protected void onPostExecute(MyNetwork network) {
updateUI(network);
}
#Override
protected MyNetwork doInBackground(Void... params) {
MyNetwork network = new MyNetwork(getApplicationContext()); // passing the context
return network;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
Two issues:
1) how do I force it to do this background task every 5 seconds. Since the network status changes every few secs (disconnection etc...), so I want it to update the UI respectively.
2) should I call it like this in MainActivity: new MyAsyncTask().execute();
Thanks all
I dont know why you called it Thread backgroundThread = new Thread() because runOnUiThread() is really the main Thread.
You should try this in an asynctask where you only update the UI in onPostExecute()
EDIT:
private class MyAsyncTask extends AsyncTask<Void, Void, String> {
private MyNetwork network;
#Override
protected void onPreExecute() {
this.network = new MyNetwork(getApplicationContext());
}
#Override
protected String doInBackground(Void... params) {
return network.getIpAddress();
}
#Override
protected void onPostExecute(String ipAddress) {
if (this.network.isConnected()){
wifiTextView.setText(R.string.wifi_is_on);
wifiTextView.setTextColor(Color.GREEN);
ipTextView.setText(ipAddress);
else {
wifiTextView.setText(R.string.wifi_is_off);
wifiTextView.setTextColor(Color.RED);
ipTextView.setText("N/A");
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
I have a specific case where I want to run an AsyncTask's doInBackground on UI Thread. How can I do that?
You definitively could, but as #Devrath said, it is pointless. AsyncTask are used for background operation.
Here is a sample that uses the runOnUiThread method:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// WORK on UI thread here
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
I ended up doing the following:
Got all the code from doInBackground and moved it to a method.
In doInBackground I make a call only to this method.
In the cases where I need the asynctask to be executed normally, I call LongOperation().execute()
In the cases where I need the asynctask to be ran on the UI thread, I dont call it but I call the method instead.
Try this
public void commentBuilder() {
new Thread(new Runnable() {
#Override
public void run() {
//Your code
}
}).start();
}
Also, see this for more detail https://stackoverflow.com/a/14038370
As far i know ..... You cannot !
AsyncTask are designed to perform background task which takes
longer time to perform
So they have to be performed in a seperate thread different from the
mainthread
Mainthread takes care of all the UI for your app
If you want ot update a UI while performing a background operation::
Just use onProgressUpdate method of the AsyncTask to update the
UI during the background operation
else use onPre method to update UI before the beckground call is
made
Else finally use onPost method to update after rte async task
completes doInBackground
{SAMPLE}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
Is there a method I could use in my Main thread, to wait for the result from an AsyncTask (in my case a value from a web-service) ?
I made a workaround without using AsyncTask but I know it's not the correct way:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Could you help with hints in order to use an AsyncTask?
Thanks.
You are looking for onPostExecute() method.
When all the work in the background is finished, onPostExecute() which is in on your main thread will be called.
#Override
protected void onPostExecute(String result) {
//Do your stuffs here on Main UI thread.
}
onPostExecute() method of AsyncTask runs in the main thread. You can rely on it to wait for a result from AsyncTask from a main thread.
private class AsyncWait extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
//Whatever is done here, will run on main thread
}
#Override
protected Void doInBackground(Void... params) {
//Whatever is done here, will run on background thread
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//Whatever is done here, will run on main thread
}
}
From the main thread:
new AsyncWait().execute();
You can just use the onPostExecute of your asynctask to call the method of your main thread, or just do whatever you need doing.
private class AsyncCaller extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
}
#Override
protected Void doInBackground(Void... params) {
...
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//this method will be running on UI thread
}
}
I have a AsysTask
class myAsyncTask extends AsyncTask<Void, Void, Integer> {
ProgressDialog progDialog;
myAsyncTask() {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progDialog = ProgressDialog.show(
SwitchArticle.this,
"Loading",
"Pleasewait",
true,
true,
new DialogInterface.OnCancelListener(){
#Override
public void onCancel(DialogInterface dialog) {
myAsyncTask.this.cancel(true);
}
}
);
}
#Override
protected Integer doInBackground(Void... arg0) {
// Call a function load Data Json...
return 1;
}
#Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (result != 1) {
progDialog.dismiss();
Toast.makeText(
SwitchArticle.this,
"Error Load Data",
Toast.LENGTH_SHORT).show();
}
else
{
//.. Bind Data To Adapter
}
progDialog.dismiss();
}
}
Call in Oncreate function :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myAsyncTask ma = new myAsyncTask();
ma.execute();
}
The first time, this code is load data and bind to listview very good.
then, i press back other activity,and comback this activity call asyntask, this code run very good.
After i back to other activity , and finish this activity call this asysntask. I press lock screen device and wait about 5 minute. i unlock device and come back activity call this asysntask. myAsynTask run doInBackGround and NOT run to onPostExcute to bind data to ListView.
Sorry because my English is very poor. I'm Vietnamese.
I think onCreate is called when you unlock the screen and go back to your activity. That means your AsyncTask will start running again... Hope that helps
The onProgressUpdate() is never called, can you tell me why?
private class LoginMe extends AsyncTask<Context, Void, Boolean> {
#Override
protected Boolean doInBackground(Context... arg0) {
doSomething();
return true;
}
#Override
protected void onProgressUpdate(Void... v) {
super.onProgressUpdate(v);
Log.d("Dev", "Im in onProgressUpdate()");
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
doOne();
} else {
doTwo();
}
}
}
You have to call publishProgress from within doInBackground manually.
doInBackground(Params...), invoked on
the background thread immediately
after onPreExecute() finishes
executing. ... 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.
http://developer.android.com/reference/android/os/AsyncTask.html