I need to perform a very simple operation that involve network. I know that this must be done with an Async Task, because run a task that involves Network operations on main thread is bad.
Since is pretty verbose using the classic way
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//to do
return "Executed";
}
#Override
protected void onPostExecute(String result) {
//to do
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
for a method static method invocation that must download only few bits
I'm wondering if there is some more concise form or alternative that I could use.
You don't need an AsyncTask. It is just a convenience to use because it already has callback methods.
You can create a new Thread and execute your network call there.
There are many ways to create a worker thread. It depends on what are you doing with network.
If you just want to do simple network operations such as download some JSON data then get it back to update UI: use AsyncTask.
If you want to do long network operations which involve moderate to large amounts of data (either uploading or downloading): use Thread.
If you want to continuously send/receive message to/from the Internet, use HandlerThread.
So in conclusion: AsyncTask is already the simplest and easiest to use. Beside, you don't need to override all methods, just override doInBackGround() and onPostExecute() if you want to receive data.
See: Asynctask vs Thread in android
You can always use AsyncTask.execute(() -> { /* network operations */ });, the downside is you don't get any of the callbacks so I tend to only use this when prototyping or with very simple tasks.
Use an anonymous class inside a method:
public void asyncOperation () {
new AsyncTask<Task, Void, Boolean>() {
#Override
protected Boolean doInBackground(String... params) {
// Your background operation, network, database, etc
return true;
}
}.execute();
}
Related
Context : networking(http request and response).
My question has two parts - one about volley and one about AsyncTask.
I'm learning to implement httpConnection using volley and AsyncTask, so please bear with me.
My question is, in what order the callbacks are called, after getting response from network? (In the case of volley and AsyncTask)
Are callbacks executed sequentially?
Consider this scenario,
I have 2 AsyncTasks. After getting response form network at same time, in what order callback will be called in postExecute()? Will both callbacks to UI thread will occur simultaneously as 2 Asynctasks are in seperate threads? or will they be executed sequentially?
I have read these SO posts,
can-i-do-a-synchronous-request-with-volley
multiple-asynctasks-onpostexecute-order
running-multiple-asynctasks-at-the-same-time-not-possible
how-to-manage-multiple-async-tasks-efficiently-in-android
how-to-synchronize-two-async-task
Thanks
Edit :
Consider this code of AsyncTask implementation,
public class AsyncTaskImplementation extends AsyncTask<String, Void, String> {
private final interface appAsyncTaskInterface;
public interface responseInterface {
void onSuccessHttpResponse(String resultJsonObject);
void onFailedHttpResponse(String failedMessage);
}
public AsyncTaskImplementation(){
//initialise
}
#Override
protected String doInBackground(String... params) {
//executeHttpRequest and return
}
#Override
protected void onPreExecute() {
//pre execute stuff like connection checking
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result != null&& !result.equals("")) {
responseInterface.onSuccessResponse(result);
} else {
responseInterface.onFailedinterface("failed");
}
}
}
Question wrt to above code :
Consider two AsyncTaskImplementation objects, A and B created in a UI thread.
Now A and B will execute a http request (assume the code is implemented).
After that they will return response through interface responseInterface.
So my question is regarding this. Will A and B simultaneously invoke callback methods in UI thread through responseInterface?
Should I use synchronized to make sure that callbacks are synchronized? Or AsyncTask ensures that callbacks are invoked sequentially?
I am developing an app that needs to process acceleration values continuously for some time (approx. an hour) - yes, I would really like to do it that way. The processing involves doing some calculations and updating the UI from time to time. The acceleration is collected inside a (foreground) service - collecting acceleration should happen if the user minimizes the app as well.
My question is: what would be the most appropriate pattern to implement this? I don't want the processing to make the app UI unresponsive.
Right now I'm collecting acceleration data in the UI thread (in the Service). The collected data is than passed to a class that does some calculations and based on them broadcasts an Intent, which is registered in the Main activity to update the UI.
Should I be collecting acceleration data in a worker thread in a service? (Is this even possible)?
Or should I do the processing in another thread? (How would be the best way to do this without starving either the UI/acceleration collection thread or the processing thread)?
Thanks!
You certainly should be doing any non-trivial processing in a background thread. The easiest way sounds like it'd just be putting it into an AsyncTask called from your existing Service. You can move your processing to doInBackground. Another option would be to create a separate IntentService to handle your processing, but I think AsyncTask should be sufficient.
Try an AsyncTask
public class AsyncTaskTestActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new PostTask().execute();
}
// The definition of our task class
private class PostTask extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
displayProgressBar("Working...");
}
#Override
protected String doInBackground(String... params) {
do_background_Stuff();
// call this method whenever you want to run something in the UI thread and then get back to processing
publishProgress(i);
}
return "All Done!";
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
updateProgressBar(values[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
dismissProgressBar();
}
}
}
Any suggestions for this kind of error which occurs when a UI thread is loaded with lots of loops and logical operations?
get the error message through data/anr/trace.txt from File explorer. And, also put all logical operations and loops into separate threads.
That ANR error happens when you are doing intensive work on UI thread and do not allow the user interface to refresh. Your description is a perfect match for this case.
To fix it run those operations on a different thread. You can also use AsyncTask if that's convenient in your situation. See http://developer.android.com/reference/android/os/AsyncTask.html
private class LongWork extends AsyncTask<Void, Integer, Void>
{
#Override
protected Void doInBackground(Void... arg0) {
//Do a long Task here
return null;
}
#Override
protected void onPostExecute(Void result) {
//Do what you have to do on the UI Thread
}
}
Then
LongWork work=new LongWork();
work.execute();
I understand that http requests should be run as part of an AsyncTask to keep it off the the UI thread. But what about the case where multiple and sequential http requests may be necessary, where the latter http requests depend on the earlier, and therefore need to be run sequentially?
In this case, is it best to put the latter AsyncTasks in the onPostExecute of the earlier AsyncTasks, to make them run sequentially?
Or does this indicate that I have the wrong approach?
To make a lot of HTTPRequests in a queue, try this:
private class QueueExample extends AsyncTask<URL, InputStream, Long> {
protected Long doInBackground(URL... urls) {
SynchronousQueue<URL> queue = new SynchronousQueue<URL>();
for(URL url : urls){
queue.add(url);
}
for (URL url : queue) {
InputStream in = new BufferedInputStream(queue.take().openConnection().getInputStream());
publishProgress(in);
}
}
protected void onProgressUpdate(InputStream... progress) {
doSomethingWithStream(progress[0]);
//Do Something
}
protected void onPostExecute(Long result) {
//Finished
}
}
If you don't have to update the UI between requests, just execute them one after another in doInBackground() and accumulate the results. When done, just return and use the result in onPostExecute() to update the UI. If you do need to update the UI, you can call publishProgress when you get some intermediate result and update in onProgressUpdate().
I am using AsyncTask on button click to refresh the screen. Following is the sequence of events that happen on btn click
progress dialog shows up
The doInBackground is called and thread is initialized which calls a web service. The web service fetches/uploads data. A pass/fail flag is set once the web service is called.
My problem is the onPostExecute is never called and therefore the screen is never refreshed.
And secondly by the time the data is downloaded and the web service sets the flag my code has already hit return stmt in doInBackground.
Question is how do i stop execution in my asynctask so that the web service is done downloading/uploading the data and finally execute onPostexecute.
FYI
I also get the following warning in eclipse
The method onPostExecute(boolean) from
the type
Screen.ConnectWebService is
never used locally
private class ConnectWebService extends AsyncTask <Void, Void, Boolean>
{
private final ProgressDialog pd = new ProgressDialog(screen.this);
protected void onPreExecute() {
pd.show(Screen.this, "Sync", "Sync in progress",true,false);
}
protected Boolean doInBackground(Void... unused) {
if (SyncInProgress == false)
{
CallWSThread();//creates thread which calls web service
}
Log.d("doInBackground","doInBackground");
return SyncStatus;
}
protected Void onPostExecute(boolean result)
{
pd.dismiss();
if (result==true) drawRadioButtons();
return null;
}
}
It should be:
protected Void onPostExecute(Boolean result)
As djg noted, you have a typo in your method declaration. You can avoid these kinds of mistakes by using the annotation #Override when you're implementing methods from a super class.