I am currently having trouble getting a value from an AsyncTask that gets data from a JSON connection. I have looked at a few examples, but mostly I have only seen posting results from AsyncTask.
First I have an object called Dog that only has a String, Name. I am trying to get the Name of the dog from the server.
Using the following code in my oncreate, I start the DogAsyncTask while assing in an URL called n and a Dog d_in.
Dog d_in = new Dog("DogName");
DogAsyncTask task = new DogAsyncTask(d_in);
String n = "www.dog.com";
task.execute(n);
Log.e("Out", d_in.getName());
My AsyncTask is as follows:
private class DogAsyncTask extends AsyncTask<String, Void, String> {
Dog d = null;
DogAsyncTask(Dog d){
this.d = d;
}
ProgressDialog mProgressDialog;
#Override
protected void onPostExecute(String result) {
d.setName(result);
Log.e("Dog", d.getName());
mProgressDialog.dismiss();
}
#Override
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(AsyncTestActivity.this, "Loading...", "Data is Loading...");
}
#Override
protected String doInBackground(String... name) {
//Go to url = name and then gets String below.
String outfromjson = "new dog name"; //This will be a function that gets a name from JSON
return outfromjson;
}
}
I tried using something like
Log.e("Out", task.d.getName());
but I keep getting the default name of the dog which is "DogName". How to I carry values out of AsyncTask?
OK, The thing what is happening here is:
You want to pass Dog as reference (pointers as in C / C++ / Objective-C),
and you want to reflect change in original variable using other variable.
but keep in mind that Java doesn't pass object by reference, Java passes objects by value (only value is transferred, another object is created and assigned value).
So what you can do is you can assign that result-holder object again as a value to the original object.
You can do the following,
Declare and implement an interface in your activity and then use it's methods as a callback from the onPostExecute method.
Related
I want to create an AsyncTask that will handle my communication with the server (the client is the android app and the server is python).
My main activity will need, depends on user interaction, send data to the server.
How can I pass the string that changes all the time to the AsyncTask?
For example, I have this variable in my main activity:
String toSend = "Something"
The user pressed a button and now the string contains this data:
toSend = "After Button Pressed"
The question is how can I pass the always changing toSend string to the Async Task?
UPDATE:
I know how to create an AsyncTask. The AsyncTask will be started at the beginning of the activity. It is not a private class in the activity. The input to the AsyncTask is dinamically changing (based in user interacts). Is there a way to have a dinamically changing input to the task? Maybe pass it by ref?
By declaring your String as final you cannot change its value. So, Declare it as
final String toSend = "After Button Pressed";
Create a constructor in your AsyncTask class and send the inpur parameters within it,
Ex:
private class ExampleAsyncTask extends AsyncTask<Void,Void, Object>{
String inputString;
public ExampleAsyncTask(String inputString){
this.inputString = inputString;
}
#Override
protected void onPreExecute(){
}
#Override
protected Object doInBackground(String... params){
//call your server here by passing the variable (this.inputString)
return result;
}
#Override
protected void onPostExecute(Object result){
}
}
//your asynctask calling part should be like this
button.setOnClickListener(new View.OnCLickListener(){
new ExampleAsyncTask(this.toSend).execute();
});
I am using AsyncTask to convert image to base64 value. The task is running in the background and the app move to next activity. How can i check the status of the AsyncTask to check if it finishes or not...
My asynctask code...
public class Asyncimg extends AsyncTask<Void, Integer, String>
{
//for converting images to base64
protected void onPreExecute (){
//disbaling sync button on converting pic to base64
}
protected String doInBackground(Void...arg0) {
Cursor cursor = mydb.getDat1();
//fetching the image location
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
for( int i=0 ; i< 1 ; i++ )
{
if( cursor.getColumnName(i) != null )
{
try
{
if( cursor.getString(i) != null )
{
//saving image to bitmap
Bitmap bitmap = BitmapFactory.decodeFile(cursor.getString(cursor.getColumnIndex(DBHelper.PHOTO)));
//converting it to base64
String en= encodeToBase64( resize(bitmap,1080,1920), Bitmap.CompressFormat.JPEG,50);
Log.d("base",en);
//inserting it to table pic
mydb.insertpic(cursor.getInt(1),en);
}
}
catch( Exception ignored)
{
}
}
}
cursor.moveToNext();
}
cursor.close();
mydb.updatebin();
return null;
}
protected void onPostExecute(String result) {
}
}
How can i check its status from another activity.?
way 1 :
make a Constance class and change value on that class and in another activity check that for new value
way 2 :
use Intent and put data and value in extras then call activity
way 3 :
create and use interface listeners
way 4:(seem good way)
use EventBus library : https://github.com/greenrobot/EventBus
any time you need sen notify to another activity via :
EventBus.getDefault().post("notify param");
then handle notify in another activity :
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent("notify param") {/* Do something */};
(for more details to using EventBus look library documents on github)
By using listeners. Follow this guide. https://guides.codepath.com/android/Creating-Custom-Listeners
You can set your return variable as "Public static" , from the current Activity Class you can call the public static variable and display its value from previous class.
Note: The value would diminish if the previous activity class is refreshed or destroyed making its value to null , from it you would probably get NullPointerException
I am calling an API through POST method and its constantly returning NULL. What could be the possible reason? I have posted the whole code. protected void onPostExecute(Void result) is actually getting NULL.
The structure of what you're doing is not right. You're using an AsyncTask with a return type of Void. The only possible value of type Void is null, so that's the only thing you can possibly get back in your onPostExecute() method. That's what happens when you return null from your doInBackground() method.
Void is appropriate for when generics force you to use a type, but you don't really need one. So you'd use it only when you don't actually need anything to be returned. In your case, where you're wanting to retrieve something that results from the call, you need a different type.
If all you want is to know whether it's succeeded or not, you could use Boolean, and have it return true when it succeeds (where you currently have return null), and false when it fails (in your catch blocks).
From the javadoc
The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.
so result is always null.
You must change your asyncTask to return something different than Void
Something like :
private class MyTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//Do request
return "response"; //return request's response as String
}
#Override
protected void onPostExecute(String result) {
if(result.equals("response")){
Toast.makeText(getApplicationContext(), "HTTP POST is working...", Toast.LENGTH_LONG).show();
} else{
Toast.makeText(getApplicationContext(), "Invalid POST req...", Toast.LENGTH_LONG).show();
}
}
}
I've been doing a bunch of research and looking over the documentation for ASyncTask in Android, but I just can't seem to wrap my head around it. I simply want to run some methods while a fragment is visible in an application, but in order to more easily do that, I think I should be using ASyncTask. My example code is as follows:
private class syncExample extends ASyncTask <Void, Void, Void>
{
#Override
protected void onPreExecute()
{
}
#Override
protected void doInBackground(Void... voids)
{
}
#Override
protected void onProgressUpdate()
{
}
#Override
protected void onPostExecute()
{
}
}
Now my questions are as follows:
In the angle brackets, I have Void, Void, Void. What exactly do those represent and how do I know what's correct to place in there?
For each method within the class, I have the each method called as void. When should they be different than void (like boolean, String, long, etc.)?
For the doInBackground method, I have Void... voids in the parenthesis. What exactly should I be putting in there? What do they represent?
Thank you for your help. The documentation on this is not very clear for a beginner like myself.
AsyncTask uses parameterized types (java generics) so that you can specify the types it uses when you define your own AsyncTask. Perhaps it's easier to explain in this form:
public abstract class AsyncTask<Params, Progress, Result> {
...
protected abstract Result doInBackground(Params... params);
protected abstract void onProgressUpdate(Progress... progress);
protected abstract void onPostExecute(Result result);
...
}
There are no classes named Params, Progress, or Result. These are instead generic types. They are just placeholders for types you wish to use when you define your own AsyncTask subclass. The above could equally be written as such:
public abstract class AsyncTask<A, B, C> {
...
protected abstract C doInBackground(A... params);
protected abstract void onProgressUpdate(B... progress);
protected abstract void onPostExecute(C result);
...
}
Suppose I were defining an AsyncTask that takes a list of Strings representing URLs, and it will ping each one to see if it's reachable, then return the number that were reachable. Meanwhile, with each test, it will update a ProgressBar as each test completes. It might look something like this:
public class MyAsyncTask extends AsyncTask<String, Integer, Integer> {
#Override
protected Integer doInBackground(String... params) {
int total = params.length;
int successfulPings = 0;
for (int i = 0; i < total; i++) {
if (isReachable(params[i])) {
successfulPings++;
}
publishProgress(i, total);
}
return successfulPings;
}
#Override
protected void onProgressUpdate(Integer... progress) {
int testsSoFar = progress[0];
int totalTests = progress[1];
progressBar.setMax(totalTests);
progressBar.setProgress(testSoFar);
}
#Override
protected void onPostExecute(Integer result) {
Toast.makeTest(context, "Reached " + result + " sites.", Toast.LENGTH_SHORT).show();
}
}
I would initiate this as follows:
String[] urls = ...
MyAsyncTask task = new MyAsyncTask();
task.execute(urls);
The argument passed into execute will be passed into doInBackground. Whatever you do in doInBackground, you need to return something that gets passed in as the argument to onPostExecute. While in doInBackground, you can call publishProgress, where you can do something like I did (but you don't have to).
My basic suggestion is to research more about AsyncTask but I'll as well try and Answer your questions:
1- In the angle brackets, I have Void, Void, Void. What exactly do those represent and how do I know what's correct to place in there?
They are the input argument types for the overridden methods: doInBackground() onPreExecute(), onProgressUpdate() and ... respectively.
2- For each method within the class, I have the each method called as void. When should they be different than void (like boolean, String,
long, etc.)?
I'll give you an example: onPostExecute() is guaranteed to be called after doInBackground(), so if onPostExecute(int someCounter) has an integer in its input, then doInBackground() should return an integer rather than void. So it will be declared like this:
int doInBackground(){
//bla bla bla
int someIntegerValue;
return someIntegerValue;
}
3- For the doInBackground() method, I have Void... voids in the parenthesis. What exactly should I be putting in there? What do they
represent?
They are var-args, basically speaking, they represent Variable number of Arguments.
Read more about them here.
Once again I suggest you delve into threading in Android and get a sense of why AsyncTask is needed.
Good Luck,
The three types used by an asynchronous task are the following:
Params, the type of the parameters sent to the task upon execution. i.e if you want to send some variable/array to your async task background task. You use that information using that variable.
Progress, the type of the progress units published during the background computation. i.e to show the progress of your background progress. ( such as showing how much a video/image is downloaded)
Result, the type of the result of the background computation. i.e the result that you calculated in background process used for passing result to onPostExecute method.
String[] username;
username[0]="user1";
username[1]="user2";
new asynctask().execute(username);
private class asynctask extends AsyncTask <USER, Integer, String>
{
#Override
protected void onPreExecute()
{
// anything you want to do prior starting the async task.
}
#Override
protected String doInBackground(USER... users)
{
int count = users.length;
for (int i = 0; i < count; i++)
retriveinformation(users[i]);
return "Hey";
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(String result) {
// the value result is HEY that is returned by doInBackground.
}
}
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void.
information taken from https://developer.android.com/reference/android/os/AsyncTask.html
Let me try my hand at this. All the info I am parsing is from the link shared by Karakuri in the comments to the question.
The angle brackets' contents, in order, are called "parameters", "progress", and "result". Parameters is the type of parameters (using varargs) that will be fed to "doInBackground". They will be receive by that method in an array. You will use these parameters as your data to work on in the background thread.
"Progress" is the types of values fed into the onProgressUpdate. When you override this method, you will take in data of this type, format it, and use it in the progress display. From my reading, it is up to you to publish your progress in doInBackground to be consumed by onProgressUpdate.
"Result" is the data type of the result of the operation. This will be the return type of doInBackground, as well as the parameter type of onPostExecute.
For parameters that include the "..." (called varargs), you can put in as many arguments as you want. They must be separated by commas, and must all be of the type specified before the "...". The items will be passed to the function in an array. So, to answer your questions:
You'll change the first parameter in the angle brackets from void when your background task needs to receive data to work on. The type will be the type of data you'd like to pass in. You'll change the second parameter when you wish to keep track of the progress. The type will be whatever type you'd like to use for keeping track, and you will need to do all the tracking yourself in "doInBackground". You'll change the third parameter when your background task needs to return data. The type will be the type of data you wish to return. The data will be supplied to "onPostExecute". This is important because AsyncTask.execute() has no return value, so you must use any necessary data in that method to get it out to the class that called AsyncTask.execute().
onPreExecute appears to always be type void. doInBackground will be of the type of result, the 3rd argument in your angle brackets. onProgressUpdate appears to always be void. onPostExecute appears to be always void.
The parameter of doInBackground will be a type label followed by the three dot and a name. The type for the label must be the same as the first parameter in the angle brackets. The name is anything you want. That name will then be assigned to an array of the type named in the type label, and passed in for you to use in the body of doInBackground.
Some thoughts: if you are a beginner, leave "progress" void for now, and don't override onProgressUpdate. It is very important in production code, but a lot of extra hard work for beginner learning projects. onPreExecute is also likely more trouble than it is worth at your level. Just remember they exist, and when you need them, you will likely know. Also, good work on not avoiding the subject of multithreading just because it is difficult.
Hi, I'm a beginner developer of android app. I do this work for a University Exam. I read more documentation but I have a problem with show a progress dialog in my activity while the asynktask download a Json String from a server that then I have to put in a listview.
In my UI thread I call the Asynk task, but the thread continue to work and I can't use the result of the httpGet(that works fine).. I understand this using a Log.i(...)
Why the UI thread dosn't stop and attend the result?? What I do Wrong?
Please help me.
package my.pack;
import java.util.concurrent.ExecutionException;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
public class TestDialogActivity extends Activity
{
ProgressDialog dialog;
String url = "My URL";
String result= "init";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DownloadJsonDataTask task = (DownloadJsonDataTask) new DownloadJsonDataTask(result).
execute(url);
try {
String ris = task.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("GET",result);
}
public String requestInfoFromServer() {
String request = null;
HttpConnection http = HttpConnection.getInstance();
http.setHttpClient(url);
request = http.executeRequest();
return request;
}
private class DownloadJsonDataTask extends AsyncTask<String, Integer, String>
{
String Result;
protected void onPreExecute()
{
dialog = new ProgressDialog(TestDialogActivity.this);
dialog.setTitle("Download");
dialog.setMessage("Please wait...");
dialog.setIndeterminate(true);
dialog.show();
}
public DownloadJsonDataTask(String response) {
this.Result=response;
}
protected String doInBackground(String... urls) {
String urldisplay = urls[0];
Log.i("STRING URL:", urldisplay);
String result = requestInfoFromServer();
return Result;
}
protected void onPostExecute(String result) {
this.Result = result;
dialog.dismiss();
}
}
}
In addition to Samir Mangroliya.
task.get(); is a blocking call for the thread the method is called from. So using it on the main UI thread you're blocking it which is bad because downloading smth may take some seconds. So the system detects the UI thread is blocked for such a long term and terminates the app with ANR (application not responding) popup. To fix this move result processing to onPostExecute() of your AsyncTask (at least the result processing should be initiated at this point, you can call some host Activity's method here passing the result).
ahh I see the problem in the doInBackground(String... urls) function you have declared two different strings with similar names now since variable names are case sensitive it is perfectly legal to have one string named Result and the other named result as R and r are seen as two different characters so thus both have unique names. how ever while this is valid syntax; this is prone to logic errors. And I believe this is where you ran into problems. you did not assign any value to Result only to result by the end of the function call which again is valid syntax and doesn't point null variable as when you declared Resultit did put in a default value of an empty string. so it will compile and not throw a null pointer error because the variable is not null, even though there is is no string data in it the pointer is still pointing at a valid spot in the memory so as far as the compiler is concerned everything is good, it's not supposed to check on the contents of the string just pass it on. meanwhile the result variable which you do assign all the data to just before the end of the call gets loaded up with all the data you want. gets completely ignored until the end of the call as there are no further commands dealing with it.and then at the end of the call it gets garbage collected and the data is never passed on as it wasn't told to pass that variable only the Result one
make sense?
In your doInBackground() routine, save the downloaded result in the member variable Result. Then, in onPostExecute() you will need to read Result and update your UI.
eg:
private void updateUI(String jsondata)
{
foo = do.something.to.derive.some.data.from.jsondata.
TextView tv = findViewById(R.id.textview1);
tv.setText (foo);
}
private class DownloadJsonDataTask extends AsyncTask<String, Integer, String>
{
String Result = null;
...
protected String doInBackground(String... urls)
{
Result = requestInfoFromServer();
}
protected void onPostExecute(String result)
{
dialog.dismiss();
updateUI(Result);
}
}