Ok, I have read a lot of questions here on StackOverflow but i still can't understand so i'm opening a new question.
I made a class which function connects to internet and fetches json as string. It works fine in normal Java Application but i can't get it work in my android project.
I'm getting next error: android.os.NetworkOnMainThreadException
So to my understanding I have to use AsyncTask but I don't know how to wrap my function into it.
Function looks like this:
public static String get(String url){
//connect and get data to string
// return string
}
Like I said it works fine in normal JavaApplication but not in android project.
Thx for help!
http://developer.android.com/reference/android/os/AsyncTask.html
Look at the sample
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
}
Your "get" function must be splitted into 2 separate function in this class
what you want to get in, put in
doInBackground
And what you want to do with data which you receive into
onPostExecute
As I understand you use AndroidHttpClient -> so you can not even try to perform your network operations in the UI thread - > so create separate thread for this purpose. You can either use AsynchTask, Thread + Handler or HandlerThread for this purpose, or you can try to experiment here with java.util.concurrent package.
NetworkOnMainThreadException | Android Developers
developer.android.com/... -
Class Overview. The exception that is thrown when an application attempts to perform a networking operation on its main thread. This is only thrown for ...
You can create the thread method which extends AsyncTask (as you correctly understood), and execute it with .execute().
Exactly how you set it up is up to you. Here's a link with a tutorial on spinning these threads:
http://www.vogella.com/articles/AndroidPerformance/article.html#concurrency_threads
Related
In my app I have a-lot of Web API calls which returns me JSON. I am trying to do this thing simple. I don't want to create AsyncTask in every fragment. I have tried many things but nothing give me the solution how to do this. I need one Class solution in which I call a method with a url argument and get result in calling fragment or activity. Can someone share best practice to do this?
I have tried otto library but It seems it don't fulfill my requirements.
Web communication should not be done in main thread, therefore, some kind of threading is necessary. I think AsyncTask is the easiest way. I suggest creating abstract class, implementing network-stuff, and leave parsing output for child classes. Something like this:
abstract class DownloadJSON extends AsyncTask<...>{
DownloadJSON(List<NameValuePair> httpParams){...}
JSONObject doInBackground(String... urls){... return mJSONObject}
abstract void onPostExecute(JSONObject json);
}
You may override doInBackground for further background parsing or just display contents in onPostExecute.
Please check the library called Retrofit. It turns your REST API into a Java interface and has asynchronous execution of requests. It even converts your JSON response into Java objects.
I also faced with the NetworkOnMainThreadException in my application but I don't see how to resolve it.
I have a class with a getter method. Like:
public ArrayList<News> get(int i){
// get the list of news from a HTML on the net. The news are split up into web pages on the site
// and i is the page number
return NewsParser(i);
}
Since Android throws the exception I come up with an idea of a downloader class which downloads the HTML content in a separate thread
pubic ArrayList<News> get(int i){
Downloader dl = new Downloader(i);
String HTMLcontent = dl.getContent(); <-- AsyncTask starts in getContent()
return NewsParser(HTMLcontent); <-- What happens here in the main thread???
}
Any ideas/best practices for this problem?
Just looking at your code and your question, it seems like you don't have a very solid understanding of how AsyncTask (or threads in general) works.
I would recommend reading this article.
Basically, your AsyncTask should query the web URL and download the data. Once the data is complete, your AsyncTask should send the HTMLContent to a handler object. The handler will be running on your main thread, so you can display the information to the user at that point.
You shouldn't be calling
dl.getContent();
to retrieve the content. AsyncTask runs on a separate thread, so you can't just call methods like this from your main thread. You need to create the Downloader object (like you did) and then call
dl.execute();
to start the AsyncTask.
run the get method inside a thread,
new Thread(new Runnable() {
#Override
public void run() {
// call get method here
}
}).start();
Since Honeycomb (Android 3.0) you can't use Networking Operations in the MainThread to avoid freezes on the Phone. This is important in order to make your app responsive.
More info:
NetworkOnMainThreadException
Responsiveness
Sorry for being a newbie, I've looked everywhere and I just don't get it.
Asynctask needs 3 parameters; e.g.
but what is the point of these parameters?
I am trying to run a geocoder in a separate thread and I have this
private class GetCurrentCity extends AsyncTask<String, Void, Void>{
but I literally made those parameters up. I have no idea what I'm supposed to put there. I don't need a progress bar or anything to be transferred to the other thread except for the line of code that is already in doInBackground() . Then I need a string to be returned from that, and I am using onPostExecute(String returnedAddress) for that.
I am confused. Help please!
From the doc of AsyncTask
The three types used by an asynchronous task are the following:
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the
background computation.
Result, the type of the result of the background computation
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Rather than an API reference, here's a little more description. First, many people will use an AsyncTask inline as an anonymous class; keep that in mind. It looks like you've extended it with your own class (which is totally fine), but it likely means you're passing the necessary data in the constructor and referencing it as class variables. In that case, some of the arguments won't make as much sense.
So picture an anonymous inline class of AsyncTask. The first thing it's going to do is run some processing in the background. To do that, you need a way to pass data to the doInBackground method (because you don't have a constructor to call and pass it data). So the first argument is the type of data you're going to pass to it. If you don't have to pass anything, use Void, or use Object, or anything at all, really, because it has to be part of the method signature but you'd ignore it anyway.
For many situations, one will want to provide progress updates. For example, you might use the Float type to represent percent complete, or Long to represent bytes read from a file, or String for general messages to a user. You use the progress type to pass out interim progress information (think of uploading a file to facebook or downloading a file, where it updates the notification status with the progress - this is where/how you'd do that). You've said you don't care about it in your case, so use Void and don't bother implementing any progress methods.
Finally, when the task completes, you need to get to the result in the onPostExecute. So your doInBackground will return a value (of this type) and the AsyncTask framework will pass it to onPostExecute. Again, this makes more sense for an anonymous class with no further body. If you'd hold any results in a class member, that's fine also (but unnecessary). If you don't need to do anything on complete, or don't need to pass any data, use Void (and return null from doInBackground). I find it's useful at the least to return a Boolean for "completed successfully or failed," so you have that information (which might influence whether you post a success or failure notification, as notification of task complete is a common onPostExecute operation).
Hope some more explanation with examples helps.
Those are for when you want to pass something to it at time of execution or passing between runInBackground and onPostExecute. You can simply make all three Void in class declaration.
AsyncTask | Android Developers
The three types used by an asynchronous task are the following:
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the
background computation.
Result, the type of the result of the background computation.
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
I'm currently developing an application on Android platform that needs to contact the main server multiple times to do various stuff. I'm now coping with the issue of software design in terms of making every request to the server in a separate thread (otherwise, I get a NetworkOnMainThreadException and it's not recommended to do so).
So I have 3 classes in my example:
The requester class that wants to, say, fill up a Spinner with data from a database located in a server.
The middle class that asks a DBConnection to perform a new connection, then wait for it to finish and parse the data to the appropriate format.
The lower class that makes the connection to the database and retrieves a raw String, which then is passed to the middle class to be parsed.
I know that for every connection made to the server, I'll have to create a new thread, so that's made in the class that establishes the connection (lower class) and waits for results. This way I don't overload the top layers of my software with AsyncTasks and stuff that they shouldn't be aware of.
The problem is that after I receive the data I have to parse it, and the do stuff with it. Also I have to fill up the spinner (as in the example).
I know it might be a good idea to make a DataFromServerListener interface or something like that, but I think it's gonna get cluttered with methods all around to handle data from server. On the other hand, I'd have to make every top class start the separate thread with an AsyncTask and might not be the best solution.
I'd really appreciate any suggestions on this subject. :D
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return "Executed";
}
#Override
protected void onPostExecute(String result) {
}
}
This is kind of what I needed. Actually, it solves problems I didn't take care of before.
http://www.codeproject.com/Articles/162201/Painless-AsyncTask-and-ProgressDialog-Usage
I have a class which reads the calllog. This could last some minutes. So I have to use a thread if I don't want to block the gui thread.
In C# I start a thread, notify the gui thread with a event when the data is ready and give the data to the gui within the event.
But how should I do it with android? What I read so far told me that's the best to use AsyncTask with android. I use it in this way (Pseudo code):
class MyClass{
private myClassVariable;
private coid startTask(){
GetDataTask data = new GetDataTask();
data.execute(varibale);
}
private void displayData{
doAnythingUsefullHere;
}
class GetDataTask extends AsyncTask<variables>{
protected variable doInBackground(variable){
return = CallLog.getData();
}
protected void onPostExecute(variable){
myclassVariable = variable;
displayData;
}
}
}
Works fine so far, but I can't cancel the thread in this way. I could cancel the task, but I have to check within the data collect loop of the calllog class if the onCancelled is called but this function is only known in the class GetDataTask and not in CallLog.
Is there a way to use AsyncTask and make "outside" classes cancelable? Or have I switch to Threads and events? What's the best way in this situation?
Could this be what you are looking for: Ideal way to cancel an executing AsyncTask ?