It is not recommended (though it is possible) to call the method get the AsyncTask inside Main Thread, because in addition to blocking a task that should be asynchronous it causes a bad user experience.With Main Thread blocked in onCreate, the user will be seeing that black screen until the task ends, at the risk of having a _.You can see more details about this in my answer: https://pt.stackoverflow.com/questions/33509/como-usar-a-biblioteca-ksoap2/33514#33514 .The best way I consider for this type of use is by using Loaders.The Loaders arose in API 11 (Android 3.0) as an adaptation of the API AsyncTask for the life cycle of both Fragments as to Activity.For versions prior to API 11, you can use Support Library v4 that it makes compatibility, just extending FragmentActivity.That means Loader is highly related to the life cycle of Activity or Fragment, and your management is done automatically by LoaderManager.An important detail to consider the use is that the first time you create the Loader it will perform processing. But in case Activity will be destroyed, no matter if the processing is over or not, it will always update the Activity correct. That means the second Activity the LoaderManager will reuse Loader previous avoiding unnecessary processing.To use one Loader, I will consider the use of Support Librarybut the calls are similar.Class APIConnectLoaderpublic class APIConnectLoader extends AsyncTaskLoader<String> {
String mResult;
String mAPIAddress;
public APIConnectLoader(Context context, String APIAddress) {
super(context);
mAPIAddress = APIAddress;
}
/****************************************************/
/** (1) A task that performs the asynchronous load **/
/****************************************************/
@Override
public String loadInBackground() {
return System.APIRequest(mAPIAddress);
}
/********************************************************/
/** (2) Deliver the results to the registered listener **/
/********************************************************/
@Override
public void deliverResult(String data) {
if(isReset()) {
releaseResources(data);
return;
}
String oldData = mResult;
mResult = data;
if(isStarted()) {
super.deliverResult(data);
}
if(oldData != null && oldData != data) {
releaseResources(oldData);
}
}
/*********************************************************/
/** (3) Implement the Loader’s state-dependent behavior **/
/*********************************************************/
@Override
protected void onStartLoading() {
if(mResult != null) {
deliverResult(mResult);
}
if (takeContentChanged() || mResult == null) {
// When the observer detects a change, it should call onContentChanged()
// on the Loader, which will cause the next call to takeContentChanged()
// to return true. If this is ever the case (or if the current data is
// null), we force a new load.
forceLoad();
}
}
@Override
public void stopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
@Override
public void onCanceled(String data) {
releaseResources(data);
}
@Override
protected void onReset() {
super.onReset();
onStopLoading();
releaseResources(mResult);
mResult = null;
}
@Override
protected void onStopLoading() {
cancelLoad();
}
protected void releaseResources(String data) {
// For a simple List, there is nothing to do. For something like a Cursor, we
// would close it in this method. All resources associated with the Loader
// should be released here.
}
public void refresh() {
mResult = null;
onContentChanged();
}
}
Class MainActivitypublic class MainActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<String> {
private static String APIAddress = "http://10.0.2.2/APIs/LOGINServer/server.php";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Inicia o Loader, ou recupera o Loader anterior caso exista
// O LoaderManager eh quem ira verificar a existencia de um Loader
// anterior
getSupportLoaderManager().initLoader(ID_DO_LOADER, null, this);
// Se nao usar o Support Library use o getLoaderManager ao inves
// do getSupportLoaderManager
}
@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
// Instancia o AsyncTaskLoader
return new APIConnectLoader(APIAddress);
}
@Override
public void onLoadFinished(Loader<String> loader, String data) {
// Atualizar UI de acordo com o resultado (data)
}
@Override
public void onLoaderReset(Loader<String> loader) {
// Nao precisa fazer nada no caso de uma String,
// Se fosse um cursor, teria que limpar recursos
// referentes ao cursor anterior
}
}
How did you do your APIConnect as an internal class of Activity and not static, the APIConnect implicitly has a reference to Activity, then just call the methods that update the IU there in the method onPostExecute.If APIConnect whether external or static, would have to use some standard to update, whether using Observer or guarding a reference the Activity.In your case, an outline would be:public class APIConnect extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {}
@Override
protected String doInBackground(String... params) {
String content;
content = System.APIRequest(APIAddress);
Log.i("HTTP Server", content);
return content;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Nesse momento podemos atualizar a UI,
// porque esse código esta sendo executado
// na Main Thread.
setTextInActivity(result);
// result é o valor de content do doInBackground
}
}
The method setTextInActivity can be declared in your Activity, that APIConnect You'll have access.Using a Inner Class a AsyncTask has an implicit reference to Activity, what is bad thinking about the life cycle of Activity, what causes one Memory Leak and given that Activity is a very large object, can cause long-term problems.O Memory Leak is caused as follows:One AsyncTask is initiated (with implicit reference to the Activity).In the meantime, before the end of AsyncTask, a Activity is destroyed. Managing a New Activity.While AsyncTask not finished, Activity destroyed will not be collected by Garbage Collector, keeping a heavy and unnecessary object in memory. And besides, when the AsyncTask finish, the old Activity is who will be updated, and may cause several errors, since it has already been destroyed.A simple solution would be to create a subclass of AsyncTask external and use the pattern Observer to update UI. Remembering to cancel AsyncTask and remove the reference from Listener when Activity is destroyed.Class APIConnectpublic class APIConnect extends AsyncTask<String, String, String> {
private APIConnectListener mListener;
// doInBackground continua o mesmo.
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(mListener != null) {
mListener.updateUI(result);
}
}
@Override
protected void onCancelled () {
// Cancelar tudo que estiver fazendo.
// Remover a referência para o Listener, a fim de evitar memory leak
mListener = null;
}
// Getter e Setter do Listener
// Definicao da interface Observer
public static interface APIConnectListener {
public void updateUI(String result);
}
}
Class Activitypublic class MainActivity extends Activity implements APIConnect.APIConnectListener {
private static String APIAddress = "http://10.0.2.2/APIs/LOGINServer/server.php";
APIConnect mAPIConnect;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAPIConnect = new APIConnect();
mAPIConnect.setAPIConnectListener(this);
mAPIConnect.execute(APIAddress);
}
@Override
public void onDestroy() {
// Cancela a AsyncTask e limpa a referência
mAPIConnect.cancel();
mAPIConnect = null;
}
@Override
public void updateUI(String result) {
// Atualiza a UI com o resultado da APIConnect
}
}
References: http://developer.android.com/guide/components/loaders.html http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html