How to know that a AsyncTasc in an external class is finished? - android

I created a class DataAdapter which launches threads to get data from webservices. When called in an activity using
DataAdapter.InitData();
how can I know when both threads are finished?
Thanks
Jul
public class DataAdapter {
private final static String URL = "http://www.mywebservice.com";
private final static String URL_AD = "http://www.mywebservice2.com";
public void InitData(){
new GetInitData().execute(URL);
new GetAd().execute(URL_AD);
}
private static class GetInitData extends AsyncTask<String, Integer, JSONObject> {
protected JSONObject doInBackground(String... urls) {
JSONObject json = RestJsonClient.getJSONObject(urls[0]);
return json;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(JSONObject json) {
//process data
}
}
private static class GetAd extends AsyncTask<String, Integer, JSONObject> {
protected JSONObject doInBackground(String... urls) {
JSONObject json = RestJsonClient.getJSONObject(urls[0]);
return json;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(JSONObject json) {
//process data
}
}
}

Use this:
public class DataAdapter {
private final String URL = "http://www.mywebservice.com";
private final String URL_AD = "http://www.mywebservice2.com";
private boolean finished = false;
public void InitData(){
new GetInitData(this).execute(URL);
new GetAd(this).execute(URL_AD);
}
public void finished(){
if(!finished){
finished = true;
}else{
Log.d("TAG","Both have finished"):
}
private class GetInitData extends AsyncTask<String, Integer, JSONObject> {
Activity ac = null;
public GetInitData(Activity ac){
this.ac=ac;
}
protected JSONObject doInBackground(String... urls) {
JSONObject json = RestJsonClient.getJSONObject(urls[0]);
return json;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(JSONObject json) {
//process data
ac.finished();
}
}
private class GetAd extends AsyncTask<String, Integer, JSONObject> {
Activity ac = null;
public GetInitData(Activity ac){
this.ac=ac;
}
protected JSONObject doInBackground(String... urls) {
JSONObject json = RestJsonClient.getJSONObject(urls[0]);
return json;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(JSONObject json) {
//process data
ac.finished();
}
}
}

Add a synchronized method to you DataAdapter class which each of the AsyncTask calles in its onPostExecute(). Within this method you set a boolean variable indicating that the first job finished, when the second AsyncTask calls the method it checks whether the first thread has already finished. If both have finished you can go one with your custom code.

Related

Get data from execute action

there is any way that I can get the return data from execute action?
for example I have the next line that calls to the execute function - googlePlacesReadTask.execute(toPass); and the googlePlacesReadTask return some parser data to me. So how can I get this data that the action return to me ?
AsyncTask -
public class PlacesDisplayTask extends AsyncTask<Object, Integer, List<HashMap<String, String>>> {
JSONObject googlePlacesJson;
GoogleMap googleMap;
#Override
protected List<HashMap<String, String>> doInBackground(Object... inputObj) {
List<HashMap<String, String>> googlePlacesList = null;
Places placeJsonParser = new Places();
try {
googlePlacesJson = new JSONObject((String) inputObj[1]);
googlePlacesList = placeJsonParser.parse(googlePlacesJson);
} catch (Exception e) {
Log.d("Exception", e.toString());
}
if(String.valueOf(googlePlacesList) != "[]"){
//Find the place
}
else{
//No place found
}
return googlePlacesList;
}
}
second AsyncTask -
public class GooglePlacesReadTask extends AsyncTask<Object, Integer, String> {
String googlePlacesData = null;
GoogleMap googleMap;
#Override
protected String doInBackground(Object... inputObj) {
try {
googleMap = (GoogleMap) inputObj[0];
String googlePlacesUrl = (String) inputObj[1];
Http http = new Http();
googlePlacesData = http.read(googlePlacesUrl);
} catch (Exception e) {
Log.d("Google Place Read Task", e.toString());
}
return googlePlacesData;
}
#Override
protected void onPostExecute(String result) {
PlacesDisplayTask placesDisplayTask = new PlacesDisplayTask();
Object[] toPass = new Object[2];
toPass[0] = googleMap;
toPass[1] = result;
placesDisplayTask.execute(toPass);
}
}
Thanks.
Based on Which type of data you want to get from that method. If that method returns String data then save it in String variable.
For example :
In your case if googlePlacesReadTask returns String type of data then store it in string variable like :
String data = googlePlacesReadTask.execute(toPass);
Hope it will help
Use the onPostExecute method of your AsyncTask, there you have the response from the service (sent by the background process), handle it as you need.
If you need the data back in your class, you can send the AsyncTask a reference to it and call one class method from your AsyncTask sending it the required data
Just one way of doing it, there are more.
Dummy example:
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
private MyClass myClass;
public MyAsyncTask(MyClass myClass) {
this.myClass = myClass;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
return something;
}
#Override
protected void onPostExecute(String something) {
super.onPostExecute(something);
if(myClass != null){
myClass.thereYouGo(something);
}
}
}
From your class (MyClass):
new MyAsyncTask(this).execute();
Receiver method in MyClass:
public void thereYouGo(String something){
// do what you want
}

onPostExecute AsyncTask not executed right after task.execute()

I have an issue with AsyncTask
String latlong = "lat=48.8534100&lon=2.3488000";
city = "Paris";
getWeather w = new getWeather(latlong,this);
w.execute();
This gs.alerter() should be executed after the onpostexecute, but it's execued before
gs.alerter("thiss" + currentWeather); //This is a Log.i function
gs.cities.add(new City(city, currentWeather + "°", image));
initializeAdapter();
The AsyncTask class is :
public class getWeather extends AsyncTask<Void, Void, JSONObject> {
String latlong;
MainActivity obj;
JSONParser jParser = new JSONParser();
JSONObject json;
public getWeather(String latlong,MainActivity obj)
{
this.latlong = latlong;
this.obj = obj;
}
#Override
protected JSONObject doInBackground(Void... params) {
// TODO Auto-generated method stub
String URL = "http://api.openweathermap.org/data/2.5/weather?" +
latlong +
"&appid=APIKEY" +
"&units=metric";
json = jParser.getJSONFromUrl(URL);
return json;
}
#Override
protected void onPostExecute(JSONObject result) {
this.obj.setWeather(result);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
}
The setweather code is on the activity class :
public void setWeather(JSONObject obj){
try {
JSONObject main = obj.getJSONObject("main");
Double initWeather = new Double(main.getString("temp"));
int finalWeather = (int)Math.round(initWeather * 1) / 1;
this.currentWeather = Integer.toString(finalWeather);
This gs.alerter() should be executed just right after the .execute()
gs.alerter(this.currentWeather);
} catch (JSONException e) {
e.printStackTrace();
}
}
So the problem is that the code just after .execute() is executed after onpostexecute(). I want to execute it in this order :
.execute()
onpostexecute() to affect the currentWeather variable
And then add City ...
Any help is needed.
Thank you all
PS : I am a beginner in Android development :)
put this code into a method:
public void methodName() {
gs.alerter("thiss" + currentWeather); //This is a Log.i function
gs.cities.add(new City(city, currentWeather + "°", image));
initializeAdapter();
}
and now:
#Override
protected void onPostExecute(JSONObject result) {
this.obj.setWeather(result);
obj.methodName();
}
Create Interface
public interface OnTaskCompleted{
void onTaskCompleted();
}
Your Activity Code will look like
class YourActivity implements OnTaskCompleted {
void someFunctionToExecute()
{
String latlong = "lat=48.8534100&lon=2.3488000";
city = "Paris";
getWeather w = new getWeather(latlong,this);
w.execute();
}
// this code will be called after postExecute
void OnTaskCompleted(){
gs.alerter("thiss" + currentWeather);
gs.cities.add(new City(city, currentWeather + "°", image));
initializeAdapter();
}
}
Your AsyncTask Code Will look like
public class getWeather extends AsyncTask<Void, Void, JSONObject> {
String latlong;
MainActivity obj;
JSONParser jParser = new JSONParser();
JSONObject json;
public getWeather(String latlong,MainActivity obj)
{
this.latlong = latlong;
this.obj = obj;
}
#Override
protected JSONObject doInBackground(Void... params) {
// TODO Auto-generated method stub
String URL = "http://api.openweathermap.org/data/2.5/weather?" +
latlong +
"&appid=APIKEY" +
"&units=metric";
json = jParser.getJSONFromUrl(URL);
return json;
}
#Override
protected void onPostExecute(JSONObject result) {
this.obj.setWeather(result);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
obj.OnTaskCompleted(); // calling after postexecute
}
}

error: method execute in class AsyncTask<Params,Progress,Result> cannot be applied to given types

I'm wanted to send text and image from android to MySQL through php. However, I get error and not able to solve. Can someone help me to figure it out the problem? Thanks a lot
Add Function
public void Add(final String claimType, final String Amount, final String Description, final Bitmap photo)
{
class AddImage extends AsyncTask<Void, Void, String> {
ProgressDialog loading;
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(getApplicationContext(), "Please Wait",null, true, true);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
#Override
protected String doInBackground(Void... params) {
HashMap<String, String> data = new HashMap<String,String>();
data.put(Configs.KEY_TYPE,claimType);
data.put(Configs.KEY_AMOUNT,Amount);
data.put(Configs.KEY_IMAGEDESCRIPTION,Description);
String uploadImage=getStringImage(photo);
data.put(Configs.KEY_IMAGE,uploadImage);
data.put(Configs.KEY_TSID,IDFromInfo);
RequestHandler rh=new RequestHandler();
String result = rh.sendPostRequest(Configs.ADD_WORKFORCE,data);
return result;
}
}
AddImage ru = new AddImage();
ru.execute(claimType, Amount, Description, photo); // error
}
Error
Error:(185, 11) error: method execute in class AsyncTask<Params,Progress,Result> cannot be applied to given types;
required: Void[]
found: String,String,String,Bitmap
reason: varargs mismatch; String cannot be converted to Void
where Params,Progress,Result are type-variables:
Params extends Object declared in class AsyncTask
Progress extends Object declared in class AsyncTask
Result extends Object declared in class AsyncTask
Try this way,
public void Add(final String claimType, final String Amount, final String Description, final Bitmap photo)
{
new AddImage().execute();
}
class AddImage extends AsyncTask<Void, Void, String> {
ProgressDialog loading;
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(getApplicationContext(), "Please Wait",null, true, true);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
#Override
protected String doInBackground(Void... params) {
HashMap<String, String> data = new HashMap<String,String>();
data.put(Configs.KEY_TYPE,claimType);
data.put(Configs.KEY_AMOUNT,Amount);
data.put(Configs.KEY_IMAGEDESCRIPTION,Description);
String uploadImage=getStringImage(photo);
data.put(Configs.KEY_IMAGE,uploadImage);
data.put(Configs.KEY_TSID,IDFromInfo);
RequestHandler rh=new RequestHandler();
String result = rh.sendPostRequest(Configs.ADD_WORKFORCE,data);
return result;
}
}
Your doInBackground expects you to pass no param (Void... params) and you pass 4 params (claimType, Amount, Description, photo)
Use AsyncTask like this :
class AddImage extends AsyncTask<String, Void, String>
and in doInBackground(String... params) get string's as :
#Override
protected String doInBackground(String... params) {
HashMap<String, String> data = new HashMap<String,String>();
data.put(Configs.KEY_TYPE,params[1]);
data.put(Configs.KEY_AMOUNT,params[2]);
data.put(Configs.KEY_IMAGEDESCRIPTION,params[3]);
}

NullPointerException in asynctask when parsing JSON

I am parsing json from url, the below code is simplified one which doesn't work. I am getting a NullPonterException at JSONObject json=jsonParser.getJSONFromUrl(GETSCHOOL_URL);.I found many people have searched for these particular problem, but I couldn't find any solution for my case.
public class SearchActivity extends Activity {
AutoCompleteTextView act;
JSONParser jsonParser;
private static final String TAG_SUCCESS = "success";
private static final String GETSCHOOL_URL = "http://sample.com/json";
private static final String TAG_STATUS = "status";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
Button b= (Button) findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new GetSchools().execute();
}
});
}
class GetSchools extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("request!", "starting");
}
#Override
protected String doInBackground(String... args) {
String success;
try {
Log.d("request!", "starting");
JSONObject json = jsonParser.getJSONFromUrl(
GETSCHOOL_URL);
Log.d("data", json.toString());
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
}
}
}
I think its silly mistake that I've done somewhere in program
You're never initializing jsonParser in the code you pasted. It needs to be initialized before your asyncTask is called.

Android generic Asynctask

I currently have multiple activity that needs to perform an asynctask for http post and I wish to make the asynctask as another class file so that the different activity can call the asynctask to perform the http post request and onPostExecute, call the method httpResult(result) in the activity that called the asynctask. I have tried to pass the activity in but I am unable to call the method in onPostExecute. How can I do that?
public class MyActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_MyActivity);
//logic here...
AsyncHttpPost asyncHttpPost = new AsyncHttpPost("someContent", this, dialog);
JSONObject data = new JSONObject();
data.put("key", "value");
try {
asyncHttpPost.execute(data);
}
catch (Exception ex){
ex.printStackTrace();
}
}
public static void httpResult(String result) {
//this method has to get called by asynctask to make changes to the UI
}
}
AsyncHttpPost.java
public class AsyncHttpPost extends AsyncTask<JSONObject, String, String> {
String recvdjson;
String mData="";
private ProgressDialog dialog;
private Activity activity;
public AsyncHttpPost(String data, Activity activity, ProgressDialog dialog) {
mData = data;
this.activity = activity;
this.dialog = dialog;
}
protected void onPreExecute()
{
dialog.show();
}
#Override
protected String doInBackground(JSONObject... params) {
//logic to do http request
return "someStringResult";
}
protected void onPostExecute(String result) {
dialog.dismiss();
activity.httpResult(result); //This line gives me error : The method httpResult(String) is undefined for the type Activity
}
}
Create an Interface called HttpResponseImpl in a seperate file and add the required method httpResult
interface HttpResponseImpl{
public void httpResult(String result);
}
Now implement this interface by you Activity class
public class MyActivity extends Activity implements HttpResponseImpl{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_MyActivity);
//logic here...
AsyncHttpPost asyncHttpPost = new AsyncHttpPost("someContent", this, dialog);
JSONObject data = new JSONObject();
data.put("key", "value");
try {
asyncHttpPost.execute(data);
}
catch (Exception ex){
ex.printStackTrace();
}
}
public void httpResult(String result){
//this method has to get called by asynctask to make changes to the UI
}
}
And your AsyncHttpPost class would be.
public class AsyncHttpPost extends AsyncTask<JSONObject, String, String> {
String recvdjson;
String mData="";
private ProgressDialog dialog;
private HttpResponseImpl httpResponseImpl;
public AsyncHttpPost(String data, HttpResponseImpl httpResponseImpl, ProgressDialog dialog) {
mData = data;
this.httpResponseImpl = httpResponseImpl;
this.dialog = dialog;
}
protected void onPreExecute()
{
dialog.show();
}
#Override
protected String doInBackground(JSONObject... params) {
//logic to do http request
return "someStringResult";
}
protected void onPostExecute(String result) {
dialog.dismiss();
httpResponseImpl.httpResult(result);
}
}
Implements this HttpResponseImpl interface with all you Activity class from which you want to do HttpRequest.
Generic AsyncTask Example
Call it like
new RetrieveFeedTask(new OnTaskFinished()
{
#Override
public void onFeedRetrieved(String feeds)
{
//do whatever you want to do with the feeds
}
}).execute("http://enterurlhere.com");
RetrieveFeedTask.class
class RetrieveFeedTask extends AsyncTask<String, Void, String>
{
String HTML_response= "";
OnTaskFinished onOurTaskFinished;
public RetrieveFeedTask(OnTaskFinished onTaskFinished)
{
onOurTaskFinished = onTaskFinished;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected String doInBackground(String... urls)
{
try
{
URL url = new URL(urls[0]); // enter your url here which to download
URLConnection conn = url.openConnection();
// open the stream and put it into BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null)
{
// System.out.println(inputLine);
HTML_response += inputLine;
}
br.close();
System.out.println("Done");
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return HTML_response;
}
#Override
protected void onPostExecute(String feed)
{
onOurTaskFinished.onFeedRetrieved(feed);
}
}
OnTaskFinished.java
public interface OnTaskFinished
{
public void onFeedRetrieved(String feeds);
}

Categories

Resources