Reputation: 397
I'm having some trouble with my coursework for my mobile programming module.
Basically I've extended Asynctask
which executes a php script which accesses my MYSQL
database depending on the input. Now one of the functions which is executed requires me to return data from the script to another class. The class order is so:
MainClass -> HelperClass -> NetworkClass(AsyncTask)
MainClass
executes the HelperClass
function 'QueryDatabase' which then creates data needed by the php script, this data is then passed to NetworkClass.
NetworkClass
then executes the database query and stores the received data (public var)
HelperClass
then pulls the data from the NetworkClass
.
MainClass
then pulls the data from the HelperClass
and its then processed.
Currently this is the best way I can think to do this as I want to keep my NetworkClass
dynamic. However the problem is that MainClass
does not wait for NetworkClass
to execute fully before trying to pull the data and so processing does not complete.
Whats the best way to do this? Can I put a delay or something between executing the database query in MainClass
and pulling the data?
Hope this makes sense.
Not too sure what code to post as I have a lot. Sorry about that.
Upvotes: 2
Views: 77
Reputation: 6154
No, never use some random delay to assume that is how long it takes for a request to complete.
What you should do is implement an interface that is used as a callback for the oncomplete of the async task. You implement this interface where you need to know when and what is returned, and then pass in the interface object to the asynctask to be called in the oncomplete method.
One other thing to think about, you may want to have your database work on a background thread as well if it can be intensive.
here is what this might look like
class EZAsyncTask extends AsyncTask<Void, Void, String>
{
private AsyncTaskListener listener;
public EZAsyncTask(AsyncTaskListener listener)
{
super();
this.listener = listener;
}
@Override
protected String doInBackground(Void... params)
{
//somethign to do
return null;
}
@Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
listener.onCompletion(result);
}
public interface AsyncTaskListener
{
public void onCompletion(String result);
}
}
the usage in your activity or whatever might look like this on a per use basis
EZAsyncTask ezTask = new EZAsyncTask(new AsyncTaskListener() {
@Override
public void onCompletion(String result)
{
// TODO handle response
}
});
ezTask.execute();
or you could just let your class/activity implement it, like you might let your activity implement an OnClickListener
Another way you could do this is through Handler, and there are other patterns you could do. But I much prefer to do it this way. easy, quick, clean.
Upvotes: 2
Reputation: 17292
The piece of code that you have in your MainClass which pulls the result, it should be asynchronous. There is no point in having it doing an active wait for the result, as it will stall the thread on which it is executing.
This is the parttern I am usually following:
private class NetworkAsyncTask extends AsyncTask<Foo, Void, Bar> {
@Override
protected Bar doInBackground(Foo... foos) {
// Use the "foos" to fetch a "bar" from your network.
}
@Override
protected void onPostExecute(Bar bar) {
// Put here your result handling code,
// don't leave it in the waiting state on the thread used in your MainClass.
}
}
Upvotes: 0