If I have an AsyncTask as a separate class, and I run the AsyncTask from an Activity, will the AsyncTask hold reference to the Activity , just like if it were an inner class of the later?
Or does it solve the issue of memory leak?
Also, will passing the context wrapped up in a WeakReference to the AsyncTask make any change?
you can use like this and get the refrense of activity
public class DeleteUserTask extends AsyncTask<String, String, String> {
private Context context;
private JSONObject Object, Object1;
public static String Success, Exception;
public static boolean isClick;
public DeleteUserTask(Context ctx) {
context = ctx;
}
#Override
protected void onPreExecute() {
OrganizationUser_EditProfileScreen.pb.setVisibility(View.VISIBLE);
}
#Override
protected String doInBackground(String... params) {
try {
ActivityBase.result = null;
Log.e("", "Request-->" + writeJSON().toString());
ActivityBase.PostMethod(context,
WebServiceLinks.UserStatusButtonTask, writeJSON());
Object = new JSONObject(ActivityBase.result);
Object1 = Object
.getJSONObject("OrganizationUserProfileButtonUpdateResult");
Success = Object1.getString("Success");
Exception = Object1.getString("Exception");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
try {
OrganizationUser_EditProfileScreen.pb.setVisibility(View.GONE);
if (ActivityBase.result != null && Success == "true") {
ActivityBase
.GeneralDialog(R.string.account, Exception, context);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public JSONObject writeJSON() {
JSONObject object = new JSONObject();
try {
object.put("OrgID", OrganizationLoginTask.OrgID);
object.put("OrgUserID", Search_Screen.OrgUserID);
object.put("Status", OrganizationUser_EditProfileScreen.Status);
object.put("ModifiedByTypeCode", "2");
object.put("ModifiedSourceCode", "8");
} catch (Exception e) {
e.printStackTrace();
}
return object;
}
}
Related
I have an app in which I am trying to get Ad id which is working fine but I want to make a singleton class with a static method which returns Ad id or exception.How do I do that
Code:-
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
AdvertisingIdClient.Info id_Info = null;
try {
id_Info = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (IOException | GooglePlayServicesNotAvailableException | GooglePlayServicesRepairableException e) {
e.printStackTrace();
}
String advertId = null;
try {
assert id_Info != null;
advertId = id_Info.getId();
Log.e(TAG, "Advertisement Id::::" + advertId);
} catch (NullPointerException e) {
e.printStackTrace();
}
return advertId;
}
};
task.execute();
IdFetcher class as below
class IdFetcher {
interface ResultCallback{
void onId(String advertId);
void onError(Exception e);
}
private IdFetcher idFetcher;
private Context context;
public IdFetcher get(Context context){
if(idFetcher == null){
idFetcher = new IdFetcher();
}
this.context = context;
return idFetcher;
}
public void fetchId(ResultCallback rcb){
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
AdvertisingIdClient.Info id_Info = null;
try {
id_Info = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (IOException | GooglePlayServicesNotAvailableException | GooglePlayServicesRepairableException e) {
context.runOnUIThread(new Runnable(){
#Override
public void run(){
rcb.onError(e);
}
});
}
String advertId = null;
try {
assert id_Info != null;
advertId = id_Info.getId();
Log.e(TAG, "Advertisement Id::::" + advertId);
} catch (NullPointerException e) {
context.runOnUIThread(new Runnable(){
#Override
public void run(){
rcb.onError(e);
}
});
}
context.runOnUIThread(new Runnable(){
#Override
public void run(){
rcb.onId(advertId);
}
});
return advertId;
}
};
task.execute();
}
}
Usage
IdFetcher.get(context).fetchId(new IdFetcher.ResultCallback(){
#Override
public void onId(String advertId){
// do something with id
}
#Override
public void onError(Exception e){
// do something with error
}
});
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
}
This is my first async task, which gets called first, it gets data from server and then onPostExecute it executes other async task, which downloads and sets image.
private class GetData extends AsyncTask<String, Void, Void> {
private final HttpClient client = new DefaultHttpClient();
private String content;
private String error = null;
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... progress) {
}
#Override
protected Void doInBackground(String... params) {
try {
HttpGet httpget = new HttpGet(params[0]);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
content = client.execute(httpget, responseHandler);
} catch (ClientProtocolException e) {
error = e.getMessage();
cancel(true);
} catch (IOException e) {
error = e.getMessage();
cancel(true);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if (error == null) {
try {
JSONObject dataDishes = new JSONObject(content);
Log.d("DISHES", dataDishes.toString());
ArrayList<DishModel> dishData = new ArrayList<DishModel>();
for (int i = 0; i < 8; i++) {
DishModel model = new DishModel();
model.setName("Company " + i);
model.setDesc("desc" + i);
//TODO: set data img
new GetImage(model).execute("http://example.com/" + (i + 1) + ".png");
dishData.add(model);
}
ListView listAllDishes = (ListView) getView().findViewById(R.id.listView);
DishRowAdapter adapterAllDishes = new DishRowAdapter(getActivity(),
R.layout.dish_row, dishData);
listAllDishes.setAdapter(adapterAllDishes);
} catch (JSONException e) {
Log.d("DISHES", e.toString());
}
} else {
Log.e("DISHES", error);
}
}
}
This is another async task, it downloads image and onPostExecute it sets image to passed model.
private class GetImage extends AsyncTask<String, Void, Void> {
private DishModel model;
private Bitmap bmp;
public getImage(DishModel model) {
this.model = model;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... progress) {
}
#Override
protected Void doInBackground(String... params) {
try {
URL url = new URL(params[0]);
Log.d("DISHES", params[0]);
try {
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (IOException e) {
Log.d("DISHES", e.toString());
}
} catch (MalformedURLException e) {
Log.d("DISHES", e.toString());
}
return null;
}
#Override
protected void onPostExecute(Void result) {
model.setPhoto(bmp);
}
}
It works if I do both data/image download proccess in one AsyncTask doInBackground(String... params), but it doesnt when I split data and image downloading into seperate async tasks. Furthermore I dont get any exceptions or errors.
UPDATE: Images shows up when i switch views..
At first, getImage and getData are classes, and classes names in Java are capitalized.
Technically, you can run another AsyncTask from onProgressUpdate() or onPostExecute() - https://stackoverflow.com/a/5780190/1159507
So, try to put the breakpoint in second AsyncTask call and debug is it called.
This class causing me android.os.NetworkOnMainThreadException,i know that i have to use asyncTask to make it but i can't figure out how because i am using 1 fragments and this make my application very slow especially when i laod bitmaps, can any one help me please.
public class ContainerData {
static public Context context;
public ContainerData() {
}
public static ArrayList<Feed> getFeeds(String feedurl){
SAXParserFactory fabrique = SAXParserFactory.newInstance();
SAXParser parseur = null;
ArrayList<Feed> feeds = null;
try {
parseur = fabrique.newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
URL url = null;
try {
url = new URL(feedurl);
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
DefaultHandler handler = new ParserXMLHandler();
try {
parseur.parse(url.openConnection().getInputStream(), handler);
feeds = ((ParserXMLHandler) handler).getData();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return feeds;
}
}
If you use AsyncTask make sure getFeeds is called inside the doInBackground(...) callback
Regardless of whether you use a fragment or not, you're still trying to perform Network activity on the main thread.
Create a generic class that extends AsyncTask which can perform all your parsing.
public class MyTaskHandler extends AsyncTask<String, Integer, Boolean>
{
#Override
protected void onPreExecute()
{
//Could display progress dialog here
}
#Override
protected Boolean doInBackground(String... params)
{
//Implement your parser here
}
#Override
protected void onPostExecute(Boolean result)
{
//Check result, dismiss dialog etc
}
}
Then create a new instance of MyTaskHandler and run it...
MyTaskHandler myTask = new MyTaskHandler();
myTask.execute("http://www.myxmlsite.com/lists.xml");
The execute method can take (String... params) so you can pass for example a URL,and retrieve it in doInBackground(String... params)
#Override
protected Boolean doInBackground(String... params)
{
//Implement your parser here
String urlToParse = params[0];
}
Best of luck.
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);
}