Now i am doing an android application.In that application I am using asynchtask class to parse json data and i have to set that values in to ui.My program is like this.
class Activity
{
textview tv;
oncreate()
{
setcontentview(layout);
tv=(textview)findviewbyid(id);
call to pageload()
}
class PageLoad extends AsyncTask<String, Void, Boolean>
{
doInBackground()
{
json parsing
tv.setText(data);
}
}
}
But I couldn't set the value from pageload class.Please help me friends.
You need to understand that doInBackground() runs on a different thread to the UI, therefore you cannot access the UI here. AsyncTask has two other methods:
onPreExecute() - before doInBackground() is run
onPostExecute() - after doInBackground() is run, can receive the result of the work done by doInBackground()
You need to pass the result of doInBackground() to onPostExecute() where you can then set the TextView's text.
I would suggest you read Google's article on how to use the Asynctask which can be found at http://developer.android.com/resources/articles/painless-threading.html and look at the class AsyncTask.
Example Code
private class MyAsynctask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
//do something heavy or resource intensive
String data = resultOfSomeWork();
return data;
}
protected void onPostExecute(String result) {
myTextView.setText(result);
}
}
you can also use onProgressUpdate() of AsyncTask
You can call it using publishProgress(values) from your doInBackGround().
And set Text in your textbox in the onProgressUpdate().
You can't use UI thread in doInBack..() of AsyncTask (As its only worker thread). Use onPostExecute() for it (If you want to make any ui related changes do in onPreExecute() or onPostExecuted()).
Just go through Android-AsyncTask and look at how it works.
You can't update UI from AsyncTask thread, it most be done on the main thread. You can use handler for this.
Related
This question already has answers here:
AsyncTask Android example
(21 answers)
Closed 9 years ago.
I have a splash screen with a TextView to displays what the app is doing such as "Updating Library"... "Updating Shipping"... etc. I'm using AsyncTask to updated my database via an API.
I'm passing the update text to the AsyncTask. I need to change the text in TextView statusMessage. I'm attempting to do this:
public class JSONParser extends AsyncTask<String, String, JSONObject> {
static InputStream is = null;
static JSONObject json = null;
static String outPut = "";
TextView statusMessage;
#Override
protected void onPreExecute() {
statusMessage = (TextView) findViewById(R.id.statusMessage);
}
...
My plan is to change the text in the doInBackground method but findViewById isn't accessible in AsyncTask. I think I need to use setContentView to allow findViewById to work but I'm not sure how.
My java file is SplashScreen.java and my xml is activity_splash_screen.xml
----- EDIT -----
For more info I have three pieces talking to each other:
SplashScreen.java -> calls to method in baseActivity.java -> method sends data to JSONParser.java -> sends parsed JSON from the API to baseActivity.java to update database
Per suggestions below I've declared
statusMessage = (TextView) findViewById(R.id.statusMessage);
In baseActivity.java's onCreate since it's the file calling the AsyncTask.
In JSONParser.java I've done this, now:
public class JSONParser extends AsyncTask<String, String, JSONObject> {
static InputStream is = null;
static JSONObject json = null;
static String outPut = "";
TextView statusMessage;
#Override
protected JSONObject doInBackground(String... params) {
// TODO Auto-generated method stub
...
}
protected void onProgressUpdate() {
statusMessage.setText("testing");
}
protected void onPostExecute(JSONObject result) {
}
}
I'm just using "testing" there for testing purposes.
My plan is to change the text in the doInBackground
Bad plan! You can't update the UI from a background Thread. You will need to do this in either onPostExecute() or onProgressUpdate().
but findViewById isn't accessible in AsyncTask.
If this is an inner class of your Activity then initialize the View in the Activity then update it in your task as described above.
If it is its own file then you will want to use an interface and have a callback to the Acitivty in onPostExecute(), onPreExecute(), or onProgressUpdate(). You can see an example of that in this SO answer.
I think I need to use setContentView to allow findViewById
Definitely! But as stated above, do this before the task such as in onCreate() of your Activity.
Edit
onProgressUpdate() takes a param but your onProgressUpdate() doesn't so it isn't the same method. That's why it complained when you had #Override which is the point of the annotation. It complains and you know you are suppose to be overriding a method so you know something is wrong with it.
Change it to
protected void onProgressUpdate(Void...values) {
statusMessage.setText("testing");
}
onProgressUpdate() link
http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)
You should use onProgressUpdate, that method has acces to the ui thread.
public class yourAsync extends AsyncTask<> {
#Override
protected void onProgressUpdate() {
textView.setText();
}
}
put something like this in your activity
Handler statusUpdateHandeler = new Handler()........
In your thread, call the handler (send it a message)
MainActivity.statusUpdateHandler.sendEmptyMessage(1);
In you actual handler code, set the status message.
I think I need to use setContentView to allow findViewById to work but I'm not sure how.
Yes. You need to use setContentView(R.layout.activity_splash_screen) in onCreate.
You can initialize your view in onCreate make asynctask an inner class of activity and update ui in onPreExecute.
TextView statusMessage;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
statusMessage = (TextView) findViewById(R.id.statusMessage);
}
Also you can use a progressdialog and display the message. I think using progressdialog would be a better choice than textview. You can publish progress in doInbackground and update progress dialog in onProgressUpdate()
http://developer.android.com/reference/android/os/AsyncTask.html
I'm trying to update a variable from AsyncTask, but I'm not exactly sure how. This is what I tried:
Outside the AsyncTask is the activity class that has a variable..:
int myVariable = 0;
MyTask hi = new MyTask ();
hi.execute();
System.out.print(myVariable);
class MyTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... args0) {
myVariable = 3;
return null;
}
}
Still prints out 0 :(
When i print out the variable, it still says 0, and not 3. I'm using AsynTask for something more complicated, but this is the dumbed down version of what I'm trying to accomplish.
You should print your variable inside the doInBackground() or the onProgressUpdate() method. Since the doInBackground() method does not run on the UI-Thread it is highly likely that the print-statement gets executed before the variable is incremented.
Like this: (assuming that "myVariable" is of type Integer, and this AsyncTask is an inner class of your Activity)
class MyTask extends AsyncTask<Void, Integer, Void> {
protected Void doInBackground(Void... args0) {
for(int i = 0; i < 100; i++) {
myVariable++;
// like this:
Log.i("Variable", "" + myVariable);
// or like this:
publishProgress(myVariable);
}
return null;
}
protected Void onProgressUpdate(Integer... prog) {
Log.i("Variable", "" + prog[0]);
}
}
Plese be aware that the for-loop I am using is just an example, you could do anything there and then update your variable and publish it. Also be aware that I changed the "Progress" type to Integer:
AsyncTask<Void, Integer, Void>
The AsyncTask main three methods are onPreExecute, doInBackground, onPostExecute.
The method onPreExecute of AsyncTask is mainly used for showing a loading/processing dialog so that until the process is completed the user interaction with the UI is disabled.
The method doInBackground of AsyncTask is mainly used for doing the background calculations or calling a web service.
The method onPostExecute of AsyncTask is mainly used for showing the output of the doInBackground method and it can be used for performing actions on the UI.
#CynthiaDDurazo: So, in your case you should use onPostExecute method to put your code System.out.println(myVariable);
I have set up an async task that will get a list of countries from a wsdl and from the result i create a bunch of country objects and add the objects to an arraylist in the country class file.
I want to be able to run this async task that will populate the array list then from another view be able to call specific indexes from the array list based on what the user has selected.
i have tried creating a class that extends AsyncTask and i have inserted the same code from the gingerbread version of the app i created which worked fine because network actions could be ran from the main thread
The type getWSDL2 must implement the inherited abstract method AsyncTask.doInBackground(Object...)
i dont have any objects to pass to this i all variables and stuff to get the wsdl data is within the async task and all the data i need from it is assigned to the arraylist from within the async task.
public class getWSDL2 extends AsyncTask {
protected void doInBackground()
{
........
}
Pass Void... as a parameter for doInBackground
protected void doInBackground(Void... params)
{
........
}
The way I understand your question you're not sure how to implement the AsyncTask because you have no need to pass values into it. All of the variables and data you need are included within the code that will execute the transaction with your server to download whatever it is you intend to display.
public class getWSDL2 extends AsyncTask {
protected Void doInBackground(Void... params) {
//All I/O code here
}
protected Void onPostExecute(){
//Anything that needs to run on the UI thread here
}
}
The general structure of the AsyncTask is listed above. The doInBackground method must contain any I/O functions while any thing you do tha touches a view, i.e. displaying the results of you're query as saved in a array list, must be called from onPostExecute, which runs on the UI thread.
From what I gather the solution is simple. Put all the code that is required for your server transaction within the doInBackground method. If you need to display the results of that transaction in a view just add a return statment to doInBackground and include the type of object/variable you will return in the varargs listed for the AsyncTask. For example if you were going to display the result of an ArrayList generated in your doInBackground method
public class getWSDL2 extends AsyncTask {
protected ArrayList<String> doInBackground(Void... params) {
//All I/O code here
return nameOfArrayListYouBuild
}
protected Void onPostExecute(ArrayList<String> whatever){
//use ArraList whatever to display your stuff
}
}
In the alternative if you don't need to display anything or run any functions on the UI thread then don't use the onPostExecute method at all.
public class getWSDL2 extends AsyncTask {
protected Void doInBackground(Void... params) {
//All I/O code here
return null
}
}
You can structure you're task so that it just uses doInBackground
I am a newbie in Android development. Now I am trying to parse. I have got many tutorials for parsing XML. But I would like to know parse XML asynchronously. I have found somewhere, xml can be loaded asynchronously using AsyncTask. Can anybody help me to find it out.
Thanks in advance
Here's a tutorial for using AsyncTask:
http://droidapp.co.uk/?p=177
And one for parsing RSS / XML:
http://droidapp.co.uk/?p=166
You need to call your parse function in doInBackground in the AsyncTask.
public class _StackOverflowActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String yourXmlString = "<put your xml String here>";
ParseXMLTask parseXMLTask = new ParseXMLTask();
parseXMLTask.execute(yourXmlString);
}
class ParseXMLTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
String yourXml = params[0];
//Parse your xml here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//do something after parsing is done
}
}
}
First, you have to extend the class AsyncTask. In my example I named it ParseXMLTask.
AsyncTask requires you to implement one method which is "doInBackground". doInBackground runs in a separate thread, put your code for parsing the xml there.
After the thread finishes, onPostExecute is called. onPostExecute runs in your main thread, you can use this if you wish to perform something after doInBackground finishes
To use ParseXMLTask, you have to instantiate it to an object. Then run the command .execute(). You can pass objects in execute similar to what I have done parseXMLTask.execute(yourXmlString); . You can pass as many variables as you like and be sure to handle them in doInBackground similar to String yourXml = params[0]; . If you have a second variable passed in .execute say... parseXml.execute(yourXmlString, my2ndVariable); , handle it in doInBackground through
String yourXml = params[0];
String the2ndVariable = params[1];
When you call .execute you tell AsyncTask to run whatever code you have placed in doInBackground in a separate thread.
I have two AsyncTasks as inner classes in my Activity. One returns an ArrayList in doInBackground and asigns a ListAdapter to it on postExecute. The other AsyncTask returns a StringArray and sets some TextViews.
On Rotation everything is gone, also the layout changes on Rotation.
I'd like to have access to the results of the doInBackground-Methods. If I had access I could just simply save the variables in onSaveInstanceState and reasign the values manually.
You can access the results of doInBackground in onPostExecute.
Simply change your class to:
public class YourTask extends AsyncTask<Void, Void, ObjectYouWantToReturn> {
#Override
protected ObjectYouWantToReturn doInBackground(Beneficiary... params) {
ObjectYouWantToReturn obj = new ObjectYouWantToReturn();
//... do your stuff
return obj;
}
#Override
protected void onPostExecute(ObjectYouWantToReturn result) {
//there you go, here you have the results from doInBackground
}
}
Shared preferences is solution of your problem i think.
revise the link given below.
http://developer.android.com/guide/topics/data/data-storage.html#pref
http://thedevelopersinfo.com/2009/11/25/getting-sharedpreferences-from-other-application-in-android/