I cant figure out why the variable "vysledek" stays unchanged after calling the void "Send" from activity. I probably doesnt fully understand the way AsyncTask works. Thanks for help.
public class Tools{
public String vysledek;
public void Send() {
Poslat Poslat = new Poslat();
Poslat.execute();
}
private class Poslat extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
vysledek = "something I want it to be";
}
#Override
protected void onPostExecute(String result){
vysledek = "something I want it to be 2";
}
}
I want that the Activity that called "Send" have the variable already. So i guess it has to wait for it to finish. I tried to do the waiting like this:
while (Tools.vysledek.equals(""))
{ }
But that causes crash.
Timing. The asnc task happens on another thread. But when the OS switches to that thread is up to the OS. It should happen quickly (next few hundred ms), but it won't necessarily be immediate, so if you immediately check for it you may or may not see it changed. The correct place to put code that requires the async task to have run is in onPostExecute.
You should assign it after the asynctask finishes
public class Tools{
public String vysledek;
public void Send() {
Poslat Poslat = new Poslat();
Poslat.execute(vysledek);
}
private class Poslat extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
}
#Override
protected void onPostExecute(String result){
vysledek = "I should be here";
}
}
Related
since im new in android development, and i need to provide an asynctask class for my http request. i have a lot of http request function type in one activity, and i want to make it dynamic. so i wanted to create only one AsyncTask function that can run all my function.
so this is the example
private class WebServiceCall extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
pBar.setVisibility(View.VISIBLE);
pBar.setIndeterminate(false);
pBar.setClickable(false);
}
#Override
protected Void doInBackground(Void... params) {
// a function that i passed
Function01();
return null;
}
#Override
protected void onPostExecute(Void result) {
try{
some code
}
}
catch(Exception e)
{
e.printStackTrace();
}
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
pBar.setClickable(true);
pBar.setVisibility(View.GONE);
}
}
and i just call like this
Oncreate(
new WebServiceCall().execute(function01());
)
any help and code sample would be appreciate,
thanks
I don't know what you mean by a function as a parameter to another function!
but you can use Interfaces for this purpose.
for example:
create an Call Back interface that can be called in onPostExecute()
public interface ResponseCallback {
void onRespond();
}
and before calling asynckTask define it like this:
ResponseCallback callback = new ResponseCallback() {
#Override
public void onRespond() {
//code to be done after calling it from onPostExecute
}
};
and pass callback to the constructor of of the asynckTask and call it in onPostExecute
of course you can modify the signature of the interface to what ever you want.
Send class object with your function and call function from object in AsyncTask.
public class A
{
//your function
int function()
{
return...;
}
}
private class WebServiceCall extends AsyncTask<Void, Void, Void> {
A myobj;
WebServiceCall(A mycustomslass)
{
myobj = mycustomclass;
}
#Override
protected void onPreExecute() {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
pBar.setVisibility(View.VISIBLE);
pBar.setIndeterminate(false);
pBar.setClickable(false);
}
#Override
protected Void doInBackground(Void... params) {
// a function that i passed
int cur = myobj.function();//this your function
return null;
}
#Override
protected void onPostExecute(Void result) {
try{
some code
}
}
catch(Exception e)
{
e.printStackTrace();
}
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
pBar.setClickable(true);
pBar.setVisibility(View.GONE);
}
}
and you can call like
Oncreate(
new WebServiceCall(new A()).execute();
)
This doesn't address your question directly, but I urge you to investigate both the fairly-well advertised problems with using AsyncTask for anything that's likely to take more than a few milliseconds, and the several really good HTTP / REST frameworks for Android, e.g. Retrofit.
When a background task returns a value how can it be accesses from another class. Just using this as example code, but what I want is the background task to do something and return a value.
protected String doInBackground(String... params) {
publishProgress("Sleeping..."); // Calls onProgressUpdate()
try {
// Do your long operations here and return the result
int time = Integer.parseInt(params[0]);
// Sleeping for given time period
Thread.sleep(time);
resp = "Slept for " + time + " milliseconds";
} catch (InterruptedException e) {
e.printStackTrace();
resp = e.getMessage();
} catch (Exception e) {
e.printStackTrace();
resp = e.getMessage();
}
**return resp;**
}
For this you need to extend asynktask class like
extends AsyncTask<String, String, String>
#Override
protected void onPostExecute(String result) {
//heare result is value you return from doInBackground() method
//this is work on UI thread
}
Classs look like
public class AsyncTaskGetResult extends AsyncTask<String, String, String> {
PrintListner mPrintListner ;
private AsyncTaskGetResult (PrintListner mPrintListner) {
this.mPrintListner = mPrintListner;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
return result;
}
#Override
protected void onPostExecute(String result) {
//heare result is value you return from doInBackground() method
//this is work on UI thread
this.mPrintListner.getResult(result);
}
}
public interface PrintListner {
public void getResult(String receiptItem);
}
If you need to access it in another class you can write listner for that and implement in you activity
public class MyActivity extends Activity implements PrintListner{
#Override
public void getResult(String receiptItem){
//Do whatever you want
}
}
and call it like new AsyncTaskGetResult(this).execute(yourString);
AsyncTask:
public class YourBackgroundTask extends AsyncTask<String, Void, String> {
private Callback callback;
public YourBackgroundTask(Callback callback){
this.callback = callback;
}
protected void doInBackground(String... strings) {
// do what you have to do
return result;
}
protected void onPostExecute(String result) {
this.callback.onDone(result);
}
public Interface Callback{
void onDone(String result);
}
}
and call it like this:
new YourBackgroundTask(yourCallback).execute(yourString);
You have a little misunderstanding. Background tasks do NOT return a value. They just do something. If you want to get a value out of some computation done in background you can make the background task so that when it finishes, it notifies some object about the resulting value.
The previous behavior can be done through the observer pattern in which an object is used to observe events from another object. In this case you want to define an observer (often called listener) and pass it to your background task.
Your listener interface may look like this:
interface ValueListener {
public void onValueComputed(int computedValue);
}
Then an implementing class looks like this:
class ValueListenerImpl implements MyListener {
#Override
public void onValueComputed(int computedValue) {
//do something...
}
}
(or you can make an anonymous class)
Your background task:
class MyAsyncTask extends AsyncTask<Void, Void, Integer> {
ValueListener listener;
public MyAsyncTask(ValueListener valueListener) {
this.listener = valueListener;
}
#Override
public Integer doInBackground(Void.. params) {
//do something...
return someValue;
}
#Override
public onPostExecute(Integer.. values) {
listener.onValueComputed(values[0]);
}
}
Finally, in your main thread you do:
...
this.valueListener = new ValueListenerImpl();
new MyAsyncTask(this.valueListener).execute();
...
This is my code:
//.___ Async task bring info from API __./
AsyncTask asyncTask = new AsyncTask() {
#Override
protected Object doInBackground(Object[] objects) {
mMovieDto = mDataSource.getPopularMovies();
return null;
}
#Override
protected void onPostExecute(Long result) {
fillList();
}
};
asyncTask.execute();
I'm getting the error that the onPostExecute is not overriding from super, witch is the right way to add this king of method to my AsyncTask?
Thanks for the help
Jose
You are missing the AsyncTask's generic types:
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> { ... }
Change your code like this:
AsyncTask asyncTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
mMovieDto = mDataSource.getPopularMovies();
return null;
}
#Override
protected void onPostExecute(Void result) {
fillList();
}
};
asyncTask.execute();
I am trying to pass a Runnable to an AsyncTask and then set the results of doInBackgroud to it and run it.
I am trying the following code with no success.
// MyActivity.java
public void click(View v) {
if(v.getId() == R.id.button) {
new AsyncHTTP(myAsyncClassCallback()).execute();
}
}
public Runnable myAsyncClassCallback() {
return new StringRunnable() {
#Override
public void run() {
Log.v(DEBUG_TAG,result.toString());
}
};
}
// StringRunnable.java
public class StringRunnable implements Runnable {
volatile String result;
public void setResult(String res) {
this.result = res;
}
#Override
public void run() {
// do something with result
}
}
// MyAsyncClass.java
public class MyAsyncClass extends AsyncTask<String, Integer, String>{
private Runnable myCallback;
public MyAsyncClass(Runnable runnable){
this.myCallback = runnable;
}
#Override
protected String doInBackground(){
// works normally
return someString;
}
#Override
protected void onPostExecute(String result) {
myCallback.setResult(result); // <--- This is my question
myCallback.run();
super.onPostExecute(result);
}
}
So I get the message:
Cannot resolve method setResult
How can I fix this? Is this some access issue?
You declared myCallback a Runnable, but Runnable does not contain a definition for setResult(String result). Your extended class, however, does. Which means you should cast the Runnable to a StringRunnable, which it actually is
((StringRunnable)myCallback).setResult(result);
Or you should declare your myCallback as a StringRunnable
private StringRunnable myCallback;
EDIT: as Unihedron pointed out, the last options means you have to change your Constructor as well
private StringRunnable myCallback;
public MyAsyncClass(StringRunnable runnable){
this.myCallback = runnable;
}
I should note, however, that it is, in your case, unnecessary to use two non-UI-threads. AsyncTask is a Thread as well
instead of
private Runnable myCallback;
use
private StringRunnable myCallback;
You'll have to cast Runnable to StringRunnable like this:
((StringRunnable)myCallback).setResult(result);
For example, I have the following class:
public class MyClass{
private static int x;
private AsyncWorker worker;
public void myVoid(){
worker = new Worker;
worker.execute();
if (x == null){
Log.v("Say something: ", "x is null");
}
}
class AsyncWorker extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
x = 10;
return null;
}
#Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
}
}
}
At the result, it prints that x is null. Is there any way to change x from AsyncTask and use it's value in future?
You need to read up on threading and the user of ASyncTask. When you call execute on your AsyncTask, myVoid goes straight on to the next line as ASyncTask is running on a different thread, so x will always be null as the AsyncTask won't have done anything yet. You're also introducing problems here with crossthreading and variable synchronisation.
In the nicest way possible, I would recommend that you take the question down and find a decent tutorial on the use of AsyncTask and threads