2

So I am new with this and I need to call function that would run AsyncTask from separate file.

MainActivity.java code

public class MainActivity extends AppCompatActivity {
String res;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Asynctasktest newAsy = new Asynctasktest();



    res = newAsy.ValidateUser();

    Toast.makeText(getBaseContext(), "'"+res+"'", Toast.LENGTH_LONG).show();
}

}

and AsyncTaskTest.java code

public class Asynctasktest extends MainActivity {

String Res;

private class GetFWork extends AsyncTask<Void,Void,String> {

    @Override
    protected void onPreExecute() {
        Res = "onPreExecute";
    }

    @Override
    protected String doInBackground(Void... param) {

        return "am i here";
    }

    @Override
    protected void onPostExecute(String Result) {
        super.onPostExecute(Result);
        Res = Result;
    }
}

public String ValidateUser(){

    final GetFWork Fl = new GetFWork();

    Fl.execute();

    return Res;
}


}

So I need to get text "am i here", but I get "onPreExecute", which shows that on first call it doesnt do doInBackground.

Ivars Akmentins
  • 55
  • 1
  • 2
  • 7
  • This is a pretty primitive way to track the happenings in your app. Use `Log` or simply debug with breakpoints. – Vucko Mar 20 '16 at 21:46
  • The first call should hit doInBackground(..)`. Add `android.os.Debug.waitForDebugger();` at the beginning of `doInBackground(..)`, put a breakpoint and see if it hits the function. – Debosmit Ray Mar 20 '16 at 21:46
  • The whole purpose of AsyncTask is that it's "async". You can't execute() it and expect to have the result inside the next line of code. – Egor Mar 20 '16 at 21:47

3 Answers3

1

This is how AsyncTask works.

res = newAsy.ValidateUser();
Toast.makeText(getBaseContext(), "'"+res+"'", Toast.LENGTH_LONG).show();

are both executed at the same time, and thus - since AsyncTask is asynchronous - the value of res is still "onPreExecute".

Wukash
  • 666
  • 5
  • 9
0

Good point made by Wukash. Just to elaborate. When ValidateUser() is returning Res, there is no guarantee that the AsyncTask has completed running, since, its asynchronous, and runs off the main thread. Hence, in your case, it returns null, since Res never got updated.

If you require returning the value result to update UI or something, send a handler function reference as callback, and make that do this work.

Please let me know if you need some further explanation. I recall having had a similar question when I was implementing an AysncTask for the first time.

Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43
  • There are tons of resources available to set up a callback. [This is a good one that I followed](http://stackoverflow.com/questions/9963691/android-asynctask-sending-callbacks-to-ui). – Debosmit Ray Mar 20 '16 at 21:51
  • I used that example and got it to work on my test. So I need to use Asynctask to do different calls to php, I will have to pass through some parameters, then like in OnPreExecute I build the link and on doInBackground I do the httpurlconnection call and wait for the answer. Or there is a better way for that? – Ivars Akmentins Mar 20 '16 at 22:25
  • @IvarsAkmentins I think you are pretty good there. Maybe move the link-building to the doInBackground also, since you really don't need it to take place synchronously. A decent OOP approach could be to instantiate an `Asynctasktest` object, initialize a bunch of parameters that you need for the link-building, and offload everything to the doInBackground. This would result in a pretty solid design. – Debosmit Ray Mar 20 '16 at 23:04
0

Try calling the super in this method

@Override
protected void onPreExecute() {
    super.onPreExecute();
    Res = "onPreExecute";
}

Also remember that you cannot call the same AsyncTask object twice or you'll get this error:

Cannot execute task: the task has already been executed (a task can be executed only once)

So the approach you have in your ValidateUser() method creating a new GetFWork() is good.

Isaac Urbina
  • 1,295
  • 11
  • 21