Android AsyncTask change - android

Why, when I change
private class DownloadTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
try {
Downloader.DownloadFromUrl("http://www.sciencemag.org/rss/news.xml", openFileOutput("Sciencemag.xml", Context.MODE_PRIVATE));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result){
mAdapter = new SiteAdapter(MainActivity.this, -1, XmlParser.getSingleItemsFromFile(MainActivity.this));
sitesList.setAdapter(mAdapter);
}
}
to
private void downloadFile(){
try {
Downloader.DownloadFromUrl("http://www.sciencemag.org/rss/news.xml", openFileOutput("Sciencemag.xml", Context.MODE_PRIVATE));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
mAdapter = new SiteAdapter(MainActivity.this, -1, XmlParser.getSingleItemsFromFile(MainActivity.this));
sitesList.setAdapter(mAdapter);
}
i get an error? I just want to call method downloadFile() instead of creating instance of inner class DownloadTask and call execute() of this instance.

The error is telling you that you cannot make network tasks on the main thread.
Look at the Android API where NetworkOnMainThreadException is defined to know more about it.
I hope this helps!

Imagine your method downloadFile() takes too long time - this will block the UI. To prevent this you should use AsyncTask which will do the background operations (downloading your file i guess) and when it is ready will update your UI. In doInBackground() put your downloadFile() method and in onPostExecute() deal with the result. Also be careful what parameters to give to your AsyncTask class.

Related

How to start AsyncTask from another class?

I would like to execute the doInBackground() method of AsyncTask inner class of my ArticleListFragment_develop.class from another class. How would i go about doing this. Please can someone help me with the syntax? I have tried a few things and i keep getting errors.
public class ArticleListFragment_develop extends ListFragment {
........
private class DownloadXmlTask extends
AsyncTask<String, Void, ArrayList<Article>> {
/*
* #Override protected void onPreExecute() { pDialog = new
* ProgressDialog(getActivity());
* pDialog.setMessage("Loading search results...");
* pDialog.setIndeterminate(true);
* pDialog.setCanceledOnTouchOutside(false); pDialog.show(); }
*/
#Override
protected ArrayList<Article> doInBackground(String... urls) {
Log.d(TAG, "DownLoadXmlTask Thread id: "
+ Thread.currentThread().getId());
try {
return loadXmlFromNetwork(urls[0]);
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return articles;
}
Write the AsyncTask in a seperate class file and use it.
new DownloadXmlTask().execute();
First read this. Then you have to have OBJECT of your async task. Write public method in your class that will be executing async task and call it. Caller object have to have reference to your fragment object.
It seems that your problem is that the inner class AsyncTask is not visible to any other class.
My suggestion is either bring the AsyncTask out of the ArticleListFragment_develop class, or create a function and call it from outside classes.

Why is AsyncTask Blocking UI Thread?

Why does my AsyncTask block the UI Thread?
My application becomes unresponsive while the AsyncTask is taking place.
This is called in the UI Thread:
new AsyncFetch().execute();
This is my AsyncTask class:
class AsyncFetch extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... args) {
String data = null;
try {
data = DataHandler.httpFetch(DataHandler.API_URL);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return data;
}
protected void onPostExecute(String data) {
DataHandler.AsyncFetchResult(data);
}
}
onPostExecute runs on the UI thread. Avoid doing too much work here. Do the heavy stuff in doInBackground and then just update the UI (or whatever you need to do) in onPostExecute.

Handle AsyncTask in Class

I am using AsyncTask Class to handle images that are coming from the server to display it in the ImageView I have one Next button in my code to call the next image using following code:
private class LoadImage extends AsyncTask<Void, Void, Void> {
#Override
protected void onPostExecute(Void result) {
if (imgque != null) {
imgSelectedQue.setImageDrawable(imgque);
if (getActivity() != null) {
adjustResourceEnvelope();
}
}
}
#Override
protected void onPreExecute() {
imgque = null;
imgSelectedQue.setImageDrawable(null);
imgSelectedQue.requestLayout();
}
#SuppressWarnings("deprecation")
#Override
protected Void doInBackground(Void... params) {
InputStream is;
try {
is = (InputStream) new URL(Constants.PLAYER_SERVICE_BASE_URL + "/playerservice"
+ imageurl).getContent();
imgque = Drawable.createFromStream(is, null);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
imgque = null;
e.printStackTrace();
}
return null;
}
}
Now the issue is that if I click the next button REPEATEDLY then it call the AsyncTask that many times and ImageView displaying all the images like "Slide-Show" because all the url images are in queue.
Is there any way to display only last AsyncTask call image?
Do something like this:
[1] When you call LoadImage AsyncTask on click of NEXT button disable NEXT button.
[2] On onPreExecute() method of your LoadImage AsyncTask enable your NEXT button again.
OR,
You can achieve such things with use of simple FLAG also. By setting it as true and false.
Hope this helps you.
Thanks.
I Found the Solution for this.If anyone facing the same issue.
I Added new lines
if (loadimage != null)
{
loadimage.cancel(true);
loadimage = null;
}
loadimage.cancel(true) will stop the AsyncTask if it is already Running
then execute the AsycTask()
loadimage = new LoadImage();
loadimage.execute();
In this way i am able to call only last AsyncTask that what I required.

How to close parent thread on Android

I would like to do step by step upload date to web service.
My code:
private Thread WebServiceThread;
public void onCreate(Bundle savedInstanceState) {
//...
WebServiceThread = new WebService();
WebServiceThread.start();
}
private class WebService extends Thread {
public void run() {
try {
new WebServiceUpload().execute("");
} catch (Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}
}
private class WebServiceUpload extends AsyncTask<String, Void, String> {
protected String doInBackground(String... data) {
// upload part
}
protected void onPostExecute(String result) {
//...
WebServiceThread = new WebService();
WebServiceThread.start();
//<Tab>__what to do here__</Tab>
//...
}
}
Now can run, but cause the device slow.
Please tell me how to close parent thread or restart parent thread way to solve this problem. (or other practice to same target.)
You don't have to chain threads like that. Just create a single AsyncTask extension that uploads the data step by step in doInBackground. If you want to publish progress reports, you can do that by calling publishProgress.
Your method of creating a WebServiceUpload from a worker thread is really bizarre and will most likely not work. AsyncTask is designed to be started from the UI thread. Just call your new WebServiceUpload().execute() from the main thread when you want to start the upload steps.
In your onPostExecute check if thread is running then force it to stop.
protected void onPostExecute(String result) {
//...
**if (WebServiceThread.isAlive())
WebServiceThread.stop();**
WebServiceThread = new WebService();
WebServiceThread.start();
//<Tab>__what to do here__</Tab>
//...
}

How can I call a statement after two asyncTask calls in Android?

I have a method like:
void doStuffs() {
new asyncCall1().execute();
new asyncCall2().execute();
}
How can I call another method after the two async calls have ended?
Use the get method to wait for the work to complete in a third async task:
(new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
asyncCall1.execute((Void)null);
asyncCall2.execute((Void)null);
try {
asyncCall1.get();
asyncCall2.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return (Void)null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}).execute((Void)null);
You need to invoke the method from the AsyncTask. The easiest way would be to wrap the statement in a public static method within your activity. Otherwise, you can pass the AsyncTask a reference to the activity. The classiest way to do it would be to use a Handler
Either way, your AsyncTask should go
#Override
onPostExecute(Result r)
{
//logic goes here
}
Maybe pass a Handler in to both the AsyncTasks which get called onPostExecute and build logic in to the handler :
Handler asyncTaskHandler = new Handler() {
private boolean firstTaskComplete = false;
#Override
public void handleMessage(Message msg) {
synchronized (firstTaskComplete ) {
if(!firstTaskComplete) {
firstTaskComplete = true;
} else {
// call some other code
}
}
}
};

Categories

Resources