lundi 21 octobre 2013

Android: Re-using AsyncTask class across multiple Activities.

First I will like to start by apologizing for not putting this up a long time ago after several email request. I have very little time to put these Tutorials together for public consumption and I prefer responding with short snippets via email. Anyway.. that aside.

This post assumes you have a basic understanding of Android Development precisely about Activities and AsyncTasks. You can visit respective links to learn more on the official android documentation.

I will try to explain how to use a single Async class across Activities that make asynchronous request to a web service.

Suppose you have a REST API that always responds with some JSON output (which we will get as a string) and you need to call this API in multiple (greater than two) Activities. It will be good to have a common AsyncTask class, where you only pass an entry-point URL and a set of parameters and it returns the response. If you however have only a single activity that does some asynchronous task, it will be good design to implement it's AsyncTask class as a private sub class. So, how can we go about implementing a single AsyncTask class to be used in multiple Activities?


  1. We will implement a sub class of the AsyncTask class which will define an interface that MUST be implemented in the calling Activity. This subclass will take as parameters the calling activity (type: Activity), method (POST or GET type: String) and a set of parameters (type:  List<namevaluepair>). Three constructors will be implemented to make the last two parameters optional.
  2. We will show a ProgressDialog while the request is being executed in the background.
  3. We demonstrate the use of this class by defining and example Activity.

A. The subclass: AsyncRequest.java

package com.sewoyebah.examples;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;

public class AsyncRequest extends AsyncTask<String, Integer, String> {

 OnAsyncRequestComplete caller;
 Context context;
 String method = "GET";
 List<NameValuePair> parameters = null;
 ProgressDialog pDialog = null;

 // Three Constructors
 public AsyncRequest(Activity a, String m, List<NameValuePair> p) {
  caller = (OnAsyncRequestComplete) a;
  context = a;
  method = m;
  parameters = p;
 }

 public AsyncRequest(Activity a, String m) {
  caller = (OnAsyncRequestComplete) a;
  context = a;
  method = m;
 }

 public AsyncRequest(Activity a) {
  caller = (OnAsyncRequestComplete) a;
  context = a;
 }

 // Interface to be implemented by calling activity
 public interface OnAsyncRequestComplete {
  public void asyncResponse(String response);
 }

 public String doInBackground(String... urls) {
  // get url pointing to entry point of API
  String address = urls[0].toString();
  if (method == "POST") {
   return post(address);
  }

  if (method == "GET") {
   return get(address);
  }

  return null;
 }

 public void onPreExecute() {
  pDialog = new ProgressDialog(context);
  pDialog.setMessage("Loading data.."); // typically you will define such
            // strings in a remote file.
  pDialog.show();
 }

 public void onProgressUpdate(Integer... progress) {
  // you can implement some progressBar and update it in this record
  // setProgressPercent(progress[0]);
 }

 public void onPostExecute(String response) {
  if (pDialog != null && pDialog.isShowing()) {
   pDialog.dismiss();
  }
  caller.asyncResponse(response);
 }

 protected void onCancelled(String response) {
  if (pDialog != null && pDialog.isShowing()) {
   pDialog.dismiss();
  }
  caller.asyncResponse(response);
 }

 @SuppressWarnings("deprecation")
 private String get(String address) {
  try {

   if (parameters != null) {

    String query = "";
    String EQ = "="; String AMP = "&";
    for (NameValuePair param : parameters) {
     query += param.getName() + EQ + URLEncoder.encode(param.getValue()) + AMP;
    }

    if (query != "") {
     address += "?" + query;
    }
   }

   HttpClient client = new DefaultHttpClient();
   HttpGet get= new HttpGet(address);

   HttpResponse response = client.execute(get);
   return stringifyResponse(response);

  } catch (ClientProtocolException e) {
   // TODO Auto-generated catch block
  } catch (IOException e) {
   // TODO Auto-generated catch block
  }

  return null;
 }

 private String post(String address) {
  try {

   HttpClient client = new DefaultHttpClient();
   HttpPost post = new HttpPost(address);

   if (parameters != null) {
    post.setEntity(new UrlEncodedFormEntity(parameters));
   }

   HttpResponse response = client.execute(post);
   return stringifyResponse(response);

  } catch (ClientProtocolException e) {
   // TODO Auto-generated catch block
  } catch (IOException e) {
   // TODO Auto-generated catch block
  }

  return null;
 }

 private String stringifyResponse(HttpResponse response) {
  BufferedReader in;
  try {
   in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

   StringBuffer sb = new StringBuffer("");
   String line = "";
   while ((line = in.readLine()) != null) {
    sb.append(line);
   }
   in.close();

   return sb.toString();
  } catch (IllegalStateException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

  return null;
 }
}

First we define the three constructors that our class should support, the first supports three parameters, the second two and the third one. Next we define the interface which the calling
Activity must implement and hence override the asyncResponse() method. Next we implement the required inherited methods. Depending on the method specified, we call the get() or post() private functions
which will return the server response that will be passed to the onPostExecute() method and back to our Activity via the implemented interface.

Please read the official Documentation on AsyncTask to have an understanding of the inherited methods. In summary onPreExecute() is called just before the request is sent, doInBackgroud() is what actually does the job and returns a value which a passed to onPostExecute() called after request is completed. If request was cancelled, onCancelled() is called instead of onPostExecute(). A typical example of a canceled request is when user rotates a device when request is not completed. If you didn't handle the activity life cycle properly then Activity will be redrawn and another request will be made (cancelling the previous).

We also use here a progressDialog to indicate to the user something  is being executed. It is initialized in the onPreExecute() method because we don't want to do this in each constructor of the class and besides we still have hold of the UI thread in the onPreExecute() method.

B. The Example Activity: PostsActivity.java

package com.sewoyebah.examples;

import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;

public class PostsActivity extends Activity implements
  AsyncRequest.OnAsyncRequestComplete {

 TextView titlesView;
 String apiURL = "http://www.example.com/apis/posts";
 ArrayList<NameValuePair> params;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_posts);

  // TODO Auto-generated method stub
  titlesView = (TextView) findViewById(R.id.post_titles);
  params = getParams();
  AsyncRequest getPosts = new AsyncRequest(this, "GET", params);
  getPosts.execute(apiURL);
 }

 // override method from AsyncRequest.OnAsyncRequestComplete interface
 // the response can contain other parameters specifying if the request was
 // successful or not and other things
 // in a real world application various checks will be done on the response
 @Override
 public void asyncResponse(String response) {

  try {
   // create a JSON array from the response string
   JSONArray objects = new JSONArray(response);
   // define a string to hold out titles (in a real word application you will be using a ListView and an Adapter to do such listing)
   String titles = "";
   String NL = "\n";
   String DOT = ". ";
   for (int i = 0; i < objects.length(); i++) {
    JSONObject object = (JSONObject) objects.getJSONObject(i);
    titles += object.getString("id") + DOT + object.getString("title") + NL;
   }
   titlesView.setText(titles);
  } catch (JSONException e) {
   e.printStackTrace();
  }
 }

 // here you specify and return a list of parameter/value pairs supported by
 // the API
 private ArrayList<NameValuePair> getParams() {
  // define and ArrayList whose elements are of type NameValuePair
  ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
  params.add(new BasicNameValuePair("start", "0"));
  params.add(new BasicNameValuePair("limit", "10"));
  params.add(new BasicNameValuePair("fields", "id,title"));
  return params;
 }

}

This is a pretty straight forward Android Activity. In this example we will assume our response is a JSON array. That is, an array of JSON Objects. For example:

 [{"id": 1, "title": "Title of post 1"}, {"id": 2, "title": "Title of post 2"}, {"id": 3, "title": "Title of post 3"}];

Observe that the class implements the AsyncRequest.OnAsyncRequestComplete interface of the AsyncRequest and hence must override the asyncResponse() method of this interface.

To execute the request in the onCreate() method, we define the set of parameters using the getParams() method, create an instance of the AsyncRequest class and call it's execute() method passing to it the entry point (URL) of your API. It is common to use and ArrayList of NameValuePairs as a paramter set.

The response will be received and parsed as a String by our AsyncRequest class and passed to the asyncResponse() interface method as a string.

In the asyncResponse(), we create a JSONArray from this string and read each object and display a list of titles. In a typical real world application, you will implement this using a ListView and an Adapter but this is out of the scope of this tutorial. Here we just concatenate the titles as a String and display in a TextView.


C. Another Example Activity: PostActivity.java

Another example of an activity could be one that gets the details of a post using the post ID. This will typically be launched as an Intent from the Listing Activity. In my next post I will try to explain the same concept using a ListView and an ArrayAdapter to display a list of posts and onClick opens the details of a post in another activity

package com.sewoyebah.examples;

import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;

public class PostActivity extends Activity implements
  AsyncRequest.OnAsyncRequestComplete {

 TextView postView;
 String apiURL = "http://www.example.com/apis/posts";
 ArrayList<NameValuePair> params;
 String postID = "75";

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_post);

  // TODO Auto-generated method stub
  postView = (TextView) findViewById(R.id.post_view);
  params = getParams();
  AsyncRequest getPosts = new AsyncRequest(this, "GET", params);
  getPosts.execute(apiURL);
 }

 // override method from AsyncRequest.OnAsyncRequestComplete interface
 @Override
 public void asyncResponse(String response) {

  try {
   // create a JSON array from the response string
   JSONObject postObject = new JSONObject(response);
   // define a string to hold out titles
   // (in a real word application you will be using a ListView and an
   // Adapter to do such listing)
   String post = "";
   String NL = "\n";
   post += postObject.getString("title") + NL + NL;
   post += postObject.getString("description");
   postView.setText(post);
  } catch (JSONException e) {
   e.printStackTrace();
  }
 }

 // here you specify and return a list of parameter/value pairs supported by
 // the API
 private ArrayList<NameValuePair> getParams() {
  // define and ArrayList whose elements are of type NameValuePair
  ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
  params.add(new BasicNameValuePair("id", postID));
  return params;
 }

}
In case you want to fully test code, bellow are the Layout xml files:

/res/layout/activity_posts.xml
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".PostsActivity" >

    <TextView
        android:id="@+id/post_titles"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

/res/layout/activity_post.xml
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".PostActivity" >

    <TextView
        android:id="@+id/post_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
So in summary after defining the AsyncRequest class this is what you do for each Activity that is to use it:

Class definition
public class MyActivity extends Activity implements AsyncRequest.OnAsyncRequestComplete

Define set of paramters:

ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", "75"));
params.add(new BasicNameValuePair("attributes", "title,description"));

Start our async task

AsyncRequest request = new AsyncRequest(this, 'GET', params);
request.execute(apiURL);

And implement our asyncResponse() method which will be called after the async request is completed

public void asyncResponse(String response) { ... }

Sending multiple asynchronous requests in same activity

One will now ask: Is it possible to send multiple asynchronous requests from same activity using the AsyncRequest class? The answer is yes but you need to add a bit more to the above solution and keep in mind there is a limit to the number of threads you can run simultaneously based on the API version your app supports. See Android documentation for details.

First you assign a label to each request and pass that label to the AsyncRequest Class and back to the asyncResponse()  method. Your constructor could be like

public AsyncRequest(Activity a, String m, List<NameValuePair> p, String l) {
  caller = (OnAsyncRequestComplete) a;
  context = a;
  method = m;
  parameters = p;
  label = l;
 }

And your interface defined as

public interface OnAsyncRequestComplete {
 public void asyncResponse(String response, String label);
}

and when calling the interface after the request is complete in the postExecute() or isCancelled()  methods you do

caller.asyncResponse(response, label);

and finally back in the Activity you implement your asyncResponse() method as follows

public void asyncResponse(String response, String label) {

 swtich(label) {
  case "get_posts_request"
  // call some method to complete the request
  // you initialized your class with new AsyncRequest(this, "GET", params, "get_posts_request")
  completeGetPostRequest(response);
  break;
  
  case "some_other_label"
  // call some method to complete the request
  // you initialized your class with new AsyncRequest(this, "POST", params, "some_other_label")
  completeSomeOtherRequest(response);
  break;
 }
   
}


Hope this gives some insights..

114 commentaires:

  1. how to use it through Fragments

    RépondreSupprimer
  2. Hi this code was working in fine in activity but not working in Fragment

    RépondreSupprimer
  3. maybe this is too late..
    But.. to make this work in Fragments you can add another custom Constructor:

    public AsyncRequest(OnAsyncRequestComplete c, Activity a, String m, List p, String l) {
    caller = c;
    context = a;
    method = m;
    parameters = p;
    label = l;
    }

    and call it like this:
    AsyncRequest getPosts = new AsyncRequest(TheFragment.this,getActivity(), "GET", params);

    RépondreSupprimer

  4. It's interesting that many of the bloggers your tips helped to clarify a few things for me as well as giving... very specific nice content.Android Training institute in chennai with placement | Android Training in chennai

    RépondreSupprimer
  5. This information is impressive; I am inspired with your post writing style & how continuously you describe this topic. After reading your post, thanks for taking the time to discuss this, I feel happy about it and I love learning more about this topic.Android Training|Android Training in chennai with placement | Android Training in velachery

    RépondreSupprimer
  6. "Great blog created by you. I read your blog, its best and useful information. You have done a great work. Super blogging and keep it up.php jobs in hyderabad.
    "

    RépondreSupprimer
  7. "Great blog created by you. I read your blog, its best and useful information. You have done a great work. Super blogging and keep it up.php jobs in hyderabad.
    "

    RépondreSupprimer
  8. Hi this code was working in fine in activity but not working in Fragmen.
    AWS Jobs in Hyderabad

    RépondreSupprimer
  9. This is very informative blog for learners, Thanks for sharing this information Android Online Training Hyderabad

    RépondreSupprimer
  10. • Nice and good article. It is very useful for me to learn and understand easily. Thanks for sharing your valuable information and time. Please keep updatingAzure Online Training HYDERABAD

    RépondreSupprimer
  11. Thanks a lot very much for the high quality and results-oriented help. I won’t think twice to endorse your blog post to anybody who wants and needs support about this area.
    digital marketing training in annanagar

    digital marketing training in marathahalli

    digital marketing training in rajajinagar

    Digital Marketing online training

    full stack developer training in pune

    RépondreSupprimer
  12. The knowledge of technology you have been sharing thorough this post is very much helpful to develop new idea. here by i also want to share this.
    full stack developer training in annanagar

    full stack developer training in tambaram

    full stack developer training in velachery

    RépondreSupprimer
  13. Really you have done great job,There are may person searching about that now they will find enough resources by your post
    python training institute in chennai
    python training in Bangalore
    python training institute in chennai

    RépondreSupprimer
  14. That was a great message in my carrier, and It's wonderful commands like mind relaxes with understand words of knowledge by information's.
    Blueprism training in Chennai

    Blueprism training in Bangalore

    Blueprism training in Pune

    RépondreSupprimer
  15. This is a nice post in an interesting line of content.Thanks for sharing this article, great way of bring this topic to discussion.

    Data Science training in Chennai
    Data science training in bangalore
    Data science online training
    Data science training in pune

    RépondreSupprimer
  16. A very nice guide. I will definitely follow these tips. Thank you for sharing such detailed article. I am learning a lot from you.

    java training in chennai | java training in bangalore

    java online training | java training in pune

    RépondreSupprimer
  17. Excellant post!!!. The strategy you have posted on this technology helped me to get into the next level and had lot of information in it.

    angularjs Training in chennai
    angularjs-Training in pune

    angularjs-Training in chennai

    angularjs Training in chennai

    angularjs-Training in tambaram

    RépondreSupprimer
  18. Whoa! I’m enjoying the template/theme of this website. It’s simple, yet effective. A lot of times it’s very hard to get that “perfect balance” between superb usability and visual appeal. I must say you’ve done a very good job with this.


    AWS Training in Bangalore | Amazon Web Services Training in bangalore , india

    AWS Training in pune | Amazon Web Services Training in Pune, india

    AWS Training in Chennai|Amazon Web Services Training in Chennai,India



    aws online training and certification | amazon web services online training ,india


    RépondreSupprimer
  19. I found your blog while searching for the updates, I am happy to be here. Very useful content and also easily understandable providing.. Believe me I did wrote an post about tutorials for beginners with reference of your blog. 
    Java training in Bangalore | Java training in Btm layout

    Java training in Bangalore | Java training in Jaya nagar

    Java training in Bangalore | Java training in Electronic city

    Java training in Chennai | Java training institute in Chennai | Java course in Chennai

    RépondreSupprimer
  20. This is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me.. 
    python Online training in chennai
    python Online training in bangalore
    python interview question and answers

    RépondreSupprimer
  21. Your good knowledge and kindness in playing with all the pieces were very useful. I don’t know what I would have done if I had not encountered such a step like this.
    Selenium Online training | Selenium Certification Online course-Gangboard

    Selenium interview questions and answers

    Selenium interview questions and answers

    RépondreSupprimer
  22. Hello! This is my first visit to your blog! We are a team of volunteers and starting a new initiative in a community in the same niche. Your blog provided us useful information to work on. You have done an outstanding job.
    AWS Training in Marathahalli | Best AWS Training in Bangalore
    Amazon Web Services Training in Chennai | No.1 AWS Training for Solution Architect in Chennai

    RépondreSupprimer
  23. Really very nice blog information for this one and more technical skills are improve,i like that kind of post.
    Python Online certification training
    python Training institute in Chennai
    Python training institute in Bangalore

    RépondreSupprimer
  24. This is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me.. 
    Python Online certification training
    python Training institute in Chennai
    Python training institute in Bangalore

    RépondreSupprimer
  25. This is quite educational arrange. It has famous breeding about what I rarity to vouch.
    Colossal proverb. This trumpet is a famous tone to nab to troths. Congratulations on a career well achieved.
    This arrange is synchronous s informative impolite festivity to pity. I appreciated what you ok extremely here.

    Selenium training in bangalore
    Selenium training in Chennai
    Selenium training in Bangalore
    Selenium training in Pune
    Selenium Online training
    Selenium interview questions and answers

    RépondreSupprimer
  26. Excellant post!!!. The strategy you have posted on this technology helped me to get into the next level and had lot of information in it.

    devops online training

    aws online training

    data science with python online training

    data science online training

    rpa online training

    RépondreSupprimer
  27. I enjoy what you guys are usually up too. This sort of clever work and coverage! Keep up the wonderful works guysl.Good going.
    honor mobile service centre in Chennai
    honor service center near me
    honor service
    honor service centres in chennai

    RépondreSupprimer
  28. Excellent article!!! Good work, your concept is really helpful for me. Thanks for your contribution in sharing such wonderful information.
    Android Training Institute in Noida
    Core PHP Training Institute in Noida

    RépondreSupprimer
  29. Ce commentaire a été supprimé par l'auteur.

    RépondreSupprimer
  30. Great post i must say thanks for the information you added to this post. I appreciate your post and looking forward for more.


    Data Science Courses

    RépondreSupprimer
  31. I just got to this amazing site not long ago. I was actually captured with the piece of resources you have got here. Big thumbs up for making such wonderful blog page!
    ExcelR Data science courses in Bangalore

    RépondreSupprimer
  32. The blog and data is excellent and informative as well


    BIG DATA COURSE MALAYSIA

    RépondreSupprimer
  33. I read a article under the same title some time ago, but this articles quality is much, much better. How you do this..
    AI learning course malaysia

    RépondreSupprimer
  34. Attend The Python training in bangalore From ExcelR. Practical Python training in bangalore Sessions With Assured Placement Support From Experienced Faculty. ExcelR Offers The Python training in bangalore.
    python training in bangalore

    RépondreSupprimer
  35. Awesome blog. I enjoyed reading your articles. This is truly a great read for me. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work!.
    Data Science Courses

    RépondreSupprimer
  36. Great Article… I love to read your articles because your writing style is too good, its is very very helpful for all of us



    You will get an introduction to the Python programming language and understand the importance of it. How to download and work with Python along with all the basics of Anaconda will be taught. You will also get a clear idea of downloading the various Python libraries and how to use them.
    Topics
    About ExcelR Solutions and Innodatatics
    Do's and Don’ts as a participant
    Introduction to Python
    Installation of Anaconda Python
    Difference between Python2 and Python3
    Python Environment
    Operators
    Identifiers
    Exception Handling (Error Handling)
    Excelr Solutions

    RépondreSupprimer
  37. Nice Post! Thank you for sharing very good post, it was so Nice to read and useful to improve my knowledge as updated one, keep blogging.
    Angular js Training in Electronic City

    RépondreSupprimer
  38. Excellent post.I want to thank you for this informative read, I really appreciate sharing this great post.Keep up your work
    rpa training in malaysia

    RépondreSupprimer
  39. punaise des lits sont l'un des problèmes les plus difficiles à éliminer rapidement.
    La meilleure solution, de loin, pour lutter contre punaise des lits est d'engager une société de lutte antiparasitaire.
    ayant de l'expérience dans la lutte contre punaise des lits . Malheureusement, cela peut être coûteux et coûteux.
    au-delà des moyens de beaucoup de gens. Si vous pensez que vous n'avez pas les moyens d'engager un professionnel
    et que vous voulez essayer de contrôler traitement des punaises de lit vous-même, il y a des choses que vous pouvez faire. Avec diligence
    et de patience et un peu de travail, vous avez une chance de vous débarrasser de punaises de lit paris dans votre maison.


    Vous voulez supprimer punaise des lits de votre maison ?
    se débarrasser de punaises de lit paris cocher ici
    nous faisons traitement des punaises de lit de façon très professionnelle.

    RépondreSupprimer
  40. In our culture, the practice of treatment through various burn fat herbs and
    spices is widely prevalent. This is mainly due to the reason that different burn fat herbs grow in great abundance here. In addition to the
    treatment of various ailments these herbs prove beneficial in Healthy Ways To Lose Weight
    , especially for those who want to burn fat herbs

    we live in a world where diseases and their prevalence has gone off
    the charts. With the ever-growing incidences of illnesses and
    sufferings, one finds themselves caught up in a loop of medications
    and doctors’ visits. We, at https://goodbyedoctor.com/ , aim to find solutions for
    all your health-related problems in the most natural and harmless ways.
    We’re a website dedicated to providing you with the best of home
    remedies, organic solutions, and show you a path towards a healthy,
    happy life. visit https://goodbyedoctor.com/
    this site daily to know more about health tips and beauty tips.

    RépondreSupprimer
  41. I Got Job in my dream company with decent 12 Lacks Per Annum Salary, I have learned this world most demanding course out there in the current IT Market from the Data Science Training in Pune Providers who helped me a lot to achieve my dreams comes true. Really worth trying.

    RépondreSupprimer
  42. I like you article. if you you want to saw Sufiyana Pyaar Mera Star Bharat Serials Full
    Sufiyana Pyaar Mera

    RépondreSupprimer
  43. traitement punaises de lit paris sont l'un des problèmes les plus difficiles à éliminer rapidement.
    La meilleure solution, de loin, pour lutter contre traitement punaises de lit paris est d'engager une société de lutte antiparasitaire.
    ayant de l'expérience dans la lutte contre traitement punaises de lit paris . Malheureusement, cela peut être coûteux et coûteux.
    au-delà des moyens de beaucoup de gens. Si vous pensez que vous n'avez pas les moyens d'engager un professionnel
    et que vous voulez essayer de contrôler traitement des punaises de lit vous-même, il y a des choses que vous pouvez faire. Avec diligence
    et de patience et un peu de travail, vous avez une chance de vous débarrasser de traitement punaises de lit dans votre maison.

    Vous voulez supprimer traitement punaises de lit paris de votre maison ?
    se débarrasser de traitement punaises de lit paris cocher ici
    nous faisons traitement des punaises de lit de façon très professionnelle.

    OR Contract Here Directly:-

    email : Sansnuisibles@gmail.com
    Address: 91 Rue de la Chapelle, 75018 Paris
    number : 0624862470

    RépondreSupprimer
  44. I wish to show thanks to you just for bailing me out of this particular trouble.As a result of checking through the net and meeting techniques that were not productive, I thought my life was done.
    Best PHP Training Institute in Chennai|PHP Course in chennai

    Best .Net Training Institute in Chennai
    Oracle DBA Training in Chennai
    RPA Training in Chennai
    UIpath Training in Chennai

    RépondreSupprimer
  45. Very useful and information content has been shared out here, Thanks for sharing it.sap hr Training in Bangalore

    RépondreSupprimer
  46. These provided information was really so nice,thanks for giving that post and the more skills to develop after refer that post.sap bw Training in Bangalore

    RépondreSupprimer
  47. Linking is very useful thing.you have really helped lots of people who visit blog and provide them use full information.sap ehs Training in Bangalore

    RépondreSupprimer
  48. Being new to the blogging world I feel like there is still so much to learn. Your tips helped to clarify a few things for me as well as giving.sap bods Training in Bangalore

    RépondreSupprimer
  49. Really it was an awesome article,very interesting to read.You have provided an nice article,Thanks for sharing.sap abap Training in Bangalore

    RépondreSupprimer
  50. I know that it takes a lot of effort and hard work to write such an informative content like this.sap fico Training in Bangalore

    RépondreSupprimer
  51. PhenQ Reviews - Is PhenQ a new Scam?
    Does it really work? Read this honest review and make a wise purchase decision. PhenQ ingredients are natural and ...
    It has been deemed fit for use in the market. It is not found to be a Scam weight loss pill.
    By far it is the safest and most effective weight loss pill available in the market today.

    Phenq reviews ..This is a powerful slimming formula made by combining the multiple weight loss
    benefits of various PhenQ ingredients. All these are conveniently contained in one pill. It helps you get the kind of body that you need. The ingredients of
    the pill are from natural sources so you don’t have to worry much about the side effects that come with other types of dieting pills.Is PhenQ safe ? yes this is completly safe.
    Where to buy PhenQ ? you can order online. you don`t know Where to order phenq check this site .

    visit https://mpho.org/ this site to know more about PhenQ Reviews.

    RépondreSupprimer

  52. Thanks for sharing your innovative ideas to our vision. I have read your blog and I gathered some new information through your blog. Your blog is really very informative and unique. Keep posting like this. Awaiting for your further update.If you are looking for any Big Data related information, please visit our website Big Data training institute in Bangalore.

    RépondreSupprimer
  53. - private detectives spain
    - private investigators in Spain at the best price. When you are obtaining the
    services offered to you by a private investigator.

    - private detective spain
    - Ways to choose private detectives spain safely | Do not make a mistake in hiring a
    private detective spain . In the regular course of your life.

    - private detectives in spain
    Ways to choose private detective in Spain safely | Do not make a mistake in hiring a
    private detective in Spain. In the regular course of your life,

    - private detective in spain
    Ways to choose private detective in spain safely | Do not make a mistake in ...
    not need to hire the professional services of a private detective agency.

    - detectives in spain
    - Ways to choose detectives in spain safely | Do not make a mistake in hiring
    a private detective in Spain. In the regular course of your life,

    - private detectives agency in spain
    - Ways to choose private detectives agency in spain safely | Do not make a mistake in hiring a
    private detective in Spain. In the regular course of your life,

    - private investigators spain
    private investigators spain at the best price. When you are obtaining the
    services offered to you by a private investigator, it is important.

    - private investigators madrid
    private investigators madrid in the Community of Madrid.
    Finding a detective in the Community of Madrid is an easy task.

    Hire private detectives from here.

    For More Info Check private investigator Here.

    RépondreSupprimer
  54. http://greenhomesgroup.com/- A 16+ year old Creative Media
    Solutions company.

    Engaged in Practical Creativity Advertising agencies in chennai for its clients from India,Europe and the US.
    A proven portfolio of work across diverseTop Graphic design studios in chennai media for its clients from different domains.
    An intricate3D augmented reality fusion of insightful strategy, cutting-edgeBranding agency in chennai
    ideas, and intelligent media integration is what we callCorporate Film Makers in chennai practical creativity.

    Check Our Website http://greenhomesgroup.com/.

    RépondreSupprimer
  55. http://karachipestcontrol. com/-Karachi Best Pest Control and Water Tank Cleaning Services.

    M/S. KarachiPestControl has very oldKarachi Pest Control Services Technical Pest Control workers
    thatfumigation services in Karachi live and add your space sevenfumigation in Karachi
    days every week.Pest services in karachiThis implies we are able toTermite Fumigation in Karachi
    be with you actuallytermite proofing in karachi quickly and keep our costs very competitive. an equivalent
    nativeUnique fumigation technician can see yourBed bugs fumigation in Karachi cuss management
    drawback through from begin to complete.Rodent Control Services Karachi Eco friendly technologies isWater tank cleaner in karachi
    also used.We are the firstWater Tank Cleaning Services in Karachi and still only professional water
    tank cleaning company in Karachi.With M/S. KarachiPestControlyou’re totallyBest Fumigation in karachi protected.


    Check Our Website http://karachipestcontrol. com/.

    RépondreSupprimer
  56. Weed Supermarket.
    Cannabis oil for sale, buy cannabis oil online, where to buy cannabis oil, cannabis oil for sale, buy cannabis oil online,
    cannabis oil for sale UK, cannabis oil for sale, where to buy cannabis oil UKBuy cbd oil, buying marijuana edibles online legal,
    online marijuana sales, buy cbd oil UK, best cbd oil UK, cheap cbd oil UK, pure thc for sale, cbd oil wholesale UK, cbd oil online buy UK
    Cbd flower for sale uk, cbd buds wholesale uk, cbd flower for sale uk, buy hemp buds uk, cheap cbd, flower uk, buy cbd buds online uk,
    cbd flowers buds uk, cbd buds for sale, cbd buds for sale uk, hemp, buds for sale uk, cbd flower for sale uk, high cbd hemp buds,
    cbd buds uk for sale, cbd buds online buy uk, hemp flowers wholesale uk, cheapest cbd flowers ukMarijuana weeds, buy marijuana weed online,
    marijuana weed in UK, marijuana weed for sale, where to order marijuana weed, cheap marijuana weed online, best quality marijuana weed,
    how to buy marijuana weed, marijuana hash, buy marijuana hash online, marijuana hash for sale, where to buy marijuana hash, buy marijuana hash online UK,
    buy marijuana hash in Germany, buy marijuana hash in Belgium, top quality marijuana hash, mail order marijuana hash, cheap marijuana hash
    You can buy Weed, Cannabis, Vape Pens & Cartridges, THC Oil Cartridges, Marijuana Seeds Online in the UK, Germany, France, Italy, Switzerland,
    Netherlands, Poland, Greece, Austria, Ukraine. We deliver fast using next Day Delivery.
    THC vape oil for sale, dank vapes for sale, buy dank vapes online, mario cartridges for sale, weed vape, thc vape, cannabis vape, weed vape oil,
    buy vape pen online, buy afghan kush online, blue dream for sale, marijuana edibles,

    Visit here https://www.dankrevolutionstore.com/ to know more.

    RépondreSupprimer
  57. I’m excited to uncover this page. I need to to thank you for ones time for this particularly fantastic read!! I definitely really liked every part of it and i also have you saved to fav to look at new information in your site.

    machine learning course

    artificial intelligence course in mumbai

    RépondreSupprimer
  58. Genuine Import Medicine.http://noelbiotech.com/Named Patient Medicine.Genuine Cancer Medicine.

    Noel Biotech is an Indian entity,Genuine Import Medicines in India facilitating access to Advanced Healthcare Solutions
    Genuine cancer medicinesrecommended for various nicheNamed Patient Medicines in India therapeutic segments. Driven by an unparallel commitment
    to assist IndianReference Listed Drugs Patients and Medical Fraternity, Noel has been consistent in its approach
    Gene Therapy Innovationsto channelize globally advanced and relevant solutions that are essential for the Indian
    scenario of Healthcare andGene Therapies for Cancer Care (Oncology) India Disease Management.

    Noel Biotech’s Brentuximab Vedotin costingvision is to enable Indian Patients to experience the Clinical
    BenefitsIpilimumab cost in India of novel medications form across the globe, anticipatingVentoclax cost in India
    Prolonged Survival with Better Quality of Life.

    Check our website-http://noelbiotech.com/

    RépondreSupprimer
  59. Buy Real Registered Passports|Drivers license(( noveltarydocuments4us@gmail.com) ID card|Visas|IELTS|TOEFL|Diplomas|Counterfeit(Whatsapp:.... +1(412)326-9821)
    Express Documents provide a second Chance In Life with New Identity protect your privacy, build new credit history, bypass criminal background checks, take back your freedom. We only offer original passports, driver's license, identity cards, visas, stamps for Australia,Germany, Belgium, Brazil, Finland, France, Great Britain, Ireland, Italy, Netherlands, Norway, Austria, Sweden, Switzerland, Spain, Great Britain, USA and some others. We offer you one of the best services in the world. Most customers have experienced our true and outstanding services.
    whatsapp :............. +1(412)326-9821Whatsapp:.............. +1(412)326-9821email:................. noveltarydocuments4us@gmail.comwebsite:.............. https://docsexperts.com

    RépondreSupprimer
  60. crowdsourcehttp://www.incruiter.com recruitment agency.

    We ’incruiter’ provide a uniquerecruitment agencies platform to various committed professionals
    placement consultancyacross the globe to use their skills and expertise to join as a recruiter and
    interviewer to empower the industry with talented human resources.Searching for the right candidate is never easy.
    job consultancy We use crowdsource recruitment to find right talent pool at much faster pace.
    Our candidate search follows application of a rigorous methodology, and a comprehensive screening to find an individual
    whorecruitment consultants is not only skilled but is also the right culture fit for your organization.
    Our interviewers are best in the industry,staffing agencies being experts from various verticals to judge right
    candidate for the job. They interview candidates taking into account primarily defined job specification of our clients and targeting
    them for needs of the organization.Thinking about payment?placement agencies Don’t worry, you pay when you hire.
    Whether you are a startup or an established enterprise, join our 10x faster recruitment process that reduces your hiring process by 50% and give you
    manpower consultancyefficient results.

    check our website:http://www.incruiter.com.

    RépondreSupprimer
  61. Really Very Infromative Post , Thanks For Sharing The Information With Us.
    AWS Training in Hyderabad
    AWS Course in Hyderabad

    RépondreSupprimer
  62. Nice article i was really impressed by seeing this article, it was very interesting and it is very useful for me.This is incredible,I feel really happy to have seen your webpage.I gained many unknown information, the way you have clearly explained is really fantastic.keep posting such useful information.
    DevOps Training in Chennai

    DevOps Online Training in Chennai

    DevOps Training in Bangalore

    DevOps Training in Hyderabad

    DevOps Training in Coimbatore

    DevOps Training

    DevOps Online Training

    RépondreSupprimer
  63. Java and Python are two of the hottest programming languages in the market right now because of their versatility, efficiency, and automation capabilities. Both languages have their merits and their flaws, but the main difference is that Java is statically typed and Python is dynamically typed.
    https://www.acte.in/java-training-in-bangalore
    https://www.acte.in/java-training-in-hyderabad
    https://www.acte.in/java-training-in-coimbatore
    https://www.acte.in/java-training


    RépondreSupprimer
  64. Nice and good article. It is very useful for me to learn and understand easily. Thanks for sharing your valuable information and time. Please keep updating

    AWS Course in Chennai

    AWS Course in Bangalore

    AWS Course in Hyderabad

    AWS Course in Coimbatore

    AWS Course

    AWS Certification Course

    AWS Certification Training

    AWS Online Training

    AWS Training


    RépondreSupprimer
  65. Thanks a lot very much for the high quality and results-oriented help. I won’t think twice to endorse your blog post to anybody who wants and needs support about this area.
    acte reviews

    acte velachery reviews

    acte tambaram reviews

    acte anna nagar reviews

    acte porur reviews

    acte omr reviews

    acte chennai reviews

    acte student reviews

    RépondreSupprimer
  66. wonderful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. This article resolved my all queries.

    Data Science Training in Hyderabad

    RépondreSupprimer
  67. Great info! I recently came across your blog and have been reading along. I thought I would leave my first comment. I don’t know what to say except that I have.

    AI Training in Hyderabad

    RépondreSupprimer
  68. Generic Latisse : Eyelashes drops 3ml with Bimatoprost 3%

    Natural Ways to Encourage eyelashes growth , iBeauty Care offers a wide variety of natural products for skin care

    iBeauty Care offers a wide variety of natural products for skin care, eyelashes growth, acne and many other health problems. All products are with clinically proven effects and great therapeutic results.
    Visit https://www.ibeauty care.com/home/21-generic-latisse.html here to buy this ar low cost.
    or visit The home page https://www.ibeauty-care.com/.

    RépondreSupprimer
  69. I respect this article for the very much investigated substance and magnificent wording. I got so included in this material that I couldn't quit perusing. I am awed with your work and aptitude. Much obliged to you to such an extent.https://eezbatteryreconditioning.com/

    RépondreSupprimer
  70. It’s really a nice and useful piece of information. I am glad that you shared this useful information with us. Please keeps us to date like this .thank you for sharing.lean belly

    RépondreSupprimer
  71. Thanks for the best blog. it was very useful for me.keep sharing such ideas in the future as well.the underground fat loss manual reviews

    RépondreSupprimer
  72. It’s really a nice and useful piece of information. I am glad that you shared this useful information with us. Please keeps us to date like this .thank you for sharing.acne no more scam

    RépondreSupprimer
  73. It’s really a nice and useful piece of information. I am glad that you shared this useful information with us. Please keeps us to date like this .thank you for sharing.https://yourfatburningfingerprint.com

    RépondreSupprimer
  74. I respect this article for the very much investigated substance and magnificent wording. I got so included in this material that I couldn't quit perusing. I am awed with your work and aptitude. Much obliged to you to such an extent.https://bestbetaswitch.com/

    RépondreSupprimer
  75. This is certainly as well a really good posting we seriously experienced looking through. It is far from on a daily basis we have risk to check out a little something.28-day keto challenge

    RépondreSupprimer
  76. Totally incredible posting! Heaps of valuable data and motivation, both of which we all need!Relay value your work keto in 28

    RépondreSupprimer
  77. I think this is an informative post and it is very beneficial and knowledgeable. Therefore, I would like to thank you for the endeavors that you have made in writing this article. All the content is absolutely well-researched. Thanks. Unlock Hip Flexors Information

    RépondreSupprimer
  78. incredible article distributed here by you. i've for a long while been itching to adapt new things with respect to this subject, and i have unquestionably adapted new things today. crypto forum

    RépondreSupprimer
  79. Great post! I am actually getting ready to across this information, It’s very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
    DevOps Training in Chennai

    DevOps Course in Chennai

    RépondreSupprimer
  80. Good To Share Information With Us Thanks For Sharing
    Android mod apk

    RépondreSupprimer
  81. Thanks for the best blog. it was very useful for me.keep sharing such ideas in the future as well. product reviews website

    RépondreSupprimer
  82. This post is so useful and informative. Keep updating with more information.....
    AWS Training in Bangalore
    AWS Course in Bangalore

    RépondreSupprimer
  83. I like your post. Everyone should do read this blog. Because this blog is important for all now I will share this post. Thank you so much for share with us.
    Telecom Tower Technician
    Career Counselling Online

    RépondreSupprimer