I'm develop my first Android Application. I tried every snipped of code i found in this page and others. Well, my problem is a need log in an user using an Internet Service, so i use an AsyncTask class, but when i tried to add an ProgressDialog into the background method, this dialog show only a second later that the background method finished. It seems like the UI is blocked while the background process is running.
This is the code of my activity and the async class.
public class PanelAdministracion extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.paneladministracion);
try {
Bundle datos = this.getIntent().getExtras();
Map<String,String> credenciales = new HashMap<String,String>();
credenciales.put("usuario", datos.getString("usuario"));
credenciales.put("password", datos.getString("password"));
new ObtenerDatos().execute(credenciales,null,null).get();
MyPagerAdapter adapter = new MyPagerAdapter(this);
ViewPager myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
private class ObtenerDatos extends AsyncTask< Map<String,String>, Void, Void>{
protected ProgressDialog progressDialog;
private final static String TAG = "LoginActivity.EfetuaLogin";
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.v(TAG, "Executando onPreExecute de EfetuaLogin");
//inicia diálogo de progresso, mostranto processamento com servidor.
progressDialog = ProgressDialog.show(PanelAdministracion.this, "Autenticando", "Contactando o servidor, por favor, aguarde alguns instantes.", true, false);
}
#Override
protected Void doInBackground(Map<String,String>... params) {
Log.d(TAG, "Executando doInBackground de EfetuaLogin");
try {
if(Usuario.login(params[0].get("usuario"), params[0].get("password"))){
Usuario.obtenerNotificaciones();
Usuario.obtenerPeliculas();
Usuario.obtenerSeries();
}else{
Intent volver = new Intent(PanelAdministracion.this,SerieslyActivity.class);
PanelAdministracion.this.startActivity(volver);
}
} catch (NotSignInException e) {
e.printStackTrace();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (DOMException e) {
e.printStackTrace();
} catch (GetDataSerieException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
progressDialog.dismiss();
}
}
}
Thank you everyone of your help!
The root point that makes your UI thread block is:
new ObtenerDatos().execute(credenciales,null,null).get();
By calling AsyncTask.get(), you are actually making you UI thread block and wait for worker thread (AKA. AsyncTask.doInBackground()) to finish. in another word, by doing that, your AsyncTask is running synchronously with UI thread. Try using:
new ObtenerDatos().execute(credenciales,null,null);
Hope this helps.
--> protected ProgressDialog progressDialog;
Write this line at class level..
I would recommend something like this...
public class PanelAdministracion extends Activity {
private ProgressDialog mProgressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.paneladministracion);
try {
Bundle datos = this.getIntent().getExtras();
Map<String,String> credenciales = new HashMap<String,String>();
credenciales.put("usuario", datos.getString("usuario"));
credenciales.put("password", datos.getString("password"));
// Keep progressDialog outside of AsyncTask...
// This all could be put in a separate method to clean things up...
mProgressDialog = ProgressDialog.show(PanelAdministracion.this, "Autenticando", "Contactando o servidor, por favor, aguarde alguns instantes.", true, false);
new AsyncTask<Map<String,String>, Void, Void>()
{
#Override
protected Void doInBackground(Map<String,String>... params) {
// Your other code goes here...
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mProgressDialog.dismiss();
}
}.execute(credenciales);
MyPagerAdapter adapter = new MyPagerAdapter(this);
ViewPager myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
Related
I have a class extends Application where I initialize some libraries needed by my application.
I want to launch a ProgressDialog from this class to notify user what App is doing.
Is possible launch these elements from Application classes??
Thanks
ps. attach my code
public class ApplicationLoader extends Application implements InitializeDelegate {
public static String TAG = "ApplicationLoader";
private ProgressDialog pd = null;
private InitializeDelegate initializeDelegate = null;
#Override
public Context getApplicationContext() {
return super.getApplicationContext();
}
#Override
public void onCreate() {
super.onCreate();
// LOAD ANDROID LIBRARY //
initializeDelegate = this;
AndroidLibraries androidLibraries = new AndroidLibraries();
androidLibraries(getApplicationContext(), initializeDelegate);
try {
pd = new ProgressDialog(getApplicationContext());
pd.setMessage("Initializing..");
pd.show();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void initializingResult(InitializinResult initializingResult) {
Log.i(TAG,""+ initializingResult);
try {
if (pd != null) {
if (pd.isShowing()) {
pd.dismiss();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Why not?
But don't do any heavy stuff in the UI Thread. You may use a splash screen in conjunction with a progress bar.
I am doing socket programming and getting JSON response. Everything is working perfectly but the only thing that is getting me in trouble is that I start another activity before getting response but I want to get all response and after that start another activity.
Here is my code.
jsonobject1.put("username", edt.getText().toString());
jsonobject1.put("udid",
"A892E0AB-6732-4F42-BEFA-3157315E9EE4");
try {
socket.emit("setPseudo", jsonobject1);
socket.emit("findAllUsers", jsonobject1);
Log.e("TAG",""+ socket.getId());
Intent intent = new Intent(MainActivity.this,
MenuScreen.class);
intent.putExtra("onlineuser", onlineuser);
intent.putExtra("finduser", finduserjson);
startActivity(intent);
In my above code I am sending JSON data to server and getting JSON object in response. But before getting the response I am being sent to another activity. So I first want response and then start activity. Help me with some pseudo code.
Thanks
Create an AsyncTask class
public class GetJSONResult extends AsyncTask<String, Void, Void>
{
ProgressDialog pd ;
private Context _context;
public GetJSONResult(Context c)
{
_context = c;
}
protected void onPreExecute()
{
super.onPreExecute();
pd = new ProgressDialog(_context);
pd.setTitle("Getting JSON details");
pd.setMessage("Please wait...");
pd.setCancelable(false);
pd.setIndeterminate(true);
pd.show();
}
#Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
try
{
jsonobject1.put("username", params[0]); // params[0] is the value passed i.e edittext value
jsonobject1.put("udid",
"A892E0AB-6732-4F42-BEFA-3157315E9EE4")
socket.emit("setPseudo", jsonobject1);
socket.emit("findAllUsers", jsonobject1);
Log.e("TAG",""+ socket.getId());
}
catch (Exception e)
{
if (pd.isShowing())
pd.dismiss();
}
return null;
}
protected void onPostExecute(Void v)
{
super.onPostExecute(v);
try
{
if (pd.isShowing())
pd.dismiss();
}
catch(Exception e)
{
}
Intent intent = new Intent(MainActivity.this,
MenuScreen.class);
intent.putExtra("onlineuser", onlineuser);
intent.putExtra("finduser", finduserjson);
startActivity(intent);
}
}
Form your MainActivity call the AsyncTask like this
public MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
// First get the reference to EditText using findViewById, then
String s = edt.getText().toString();
// Call the AsyncTask
new GetJSONResult(MainActivity.this).execute(s); // pass the edittext value to doInBackGround method.
}
}
private class getResponse extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
jsonobject1.put("username", edt.getText().toString());
jsonobject1.put("udid",
"A892E0AB-6732-4F42-BEFA-3157315E9EE4");
try {
socket.emit("setPseudo", jsonobject1);
socket.emit("findAllUsers", jsonobject1);
Log.e("TAG",""+ socket.getId());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
Intent intent = new Intent(MainActivity.this,
MenuScreen.class);
intent.putExtra("onlineuser", onlineuser);
intent.putExtra("finduser", finduserjson);
startActivity(intent);
}
#Override
protected void onCancelled() {
super.onCancelled();
progressDialog.dismiss();
}
}
and for executing new getResponse().execute();
i am trying to access saved preferences from within an asynctask but i always keep getting the error "preferences can not be resolved". Any ideas? Here is a part of the code:
public class Login extends SherlockActivity {
SharedPreferences preferences;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
new LongOperationLogin(this).execute();
}
}
class LongOperationLogin extends AsyncTask<String, Void, String> {
private Login longOperationContext = null;
public LongOperationLogin(Login context) {
longOperationContext = context;
}
#Override
protected String doInBackground(String... params) {
//THIS IS WHERE I NEED THE VALUE
String username = this.preferences.getString("username", "n/a");
try {
//JSON fetching
}
} catch (MalformedURLException e) {
e.printStackTrace();
Log.v("Error", "URL exc");
} catch (IOException e) {
e.printStackTrace();
Log.v("ERROR", "IOEXECPTOIn");
} catch (JSONException e) {
e.printStackTrace();
Log.v("Error", "JsonException");
}
return null;
}
#Override
protected void onPostExecute(String result) {
}
}
protected void onPreExecute() {
}
protected void onProgressUpdate(Void... values) {
}
}
Thanks in advance!
Robert
You should access your preferece variable with Login.this.preferences. Also make sure that your AsyncTask is an inner class (contained in Login).
Try this
String username = longOperationContext.preferences.getString("username", "n/a");
and make preferences field public
I want to display a Progress Dialog while I have two threads running one after the other, but my data structure that I use gets populated via the threads, becomes null. Thus I used thread.get() method to wait for the thread to be finished....not sure how I can get around this here is an example of one of my Async Threads:
private void performDetailSearch(String reference) {
String addplus = searchterm.replace(" ", "+");
RestClientDS restpSd = new RestClientDS();
String url = PLACES_DETAILS_URL +"reference="+ reference + "&sensor=false&key=" + API_KEY;
Log.d("url",url);
String[] URL = {url};
restpSd.execute(URL);
try {
restpSd.get();
}
catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
catch (ExecutionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
Use AsyncTask instead of Thread and call another task after one gets completed.
AsyncTask can be called this way new FetchData().execute();
private class FetchData extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog = new ProgressDialog(HomeActivity.this);
/** progress dialog to show user that the backup is processing. */
/** application context. */
protected void onPreExecute() {
this.dialog.setMessage(getResources().getString(
R.string.Loading_String));
this.dialog.show();
}
protected Boolean doInBackground(final String... args) {
try {
//do your background work
return true;
} catch (Exception e) {
Log.e("tag", "error", e);
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (success) {
//call the another asynctask from here.
// new FetchData2().execute();
}
}
}
Am building application for company events , i got the events from database and fill it in the adapter for ListView, i need to display ProgressDialog during the retrieving data from database , this is my code
`
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.listlayout);
adapter = new MyArrayAdapter(this);
listView = (ListView) findViewById(R.id.list);
progressDialog = ProgressDialog.show(this, "Please wait....",
"Here your message");
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
//this is call the webservice to got filled adapter
adapter = new EventWebservice().getAdapter(this);
listView.setAdapter(adapter);
progressDialog.dismiss();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
`
What i say is make use of AsyncTask().. show ypur dialog in preExecute() and dismiss in postexecute();.. and the data fetching code u put in backGround task.. i mean like below.. this is a sample code i ve used in my project
class Backgrountask extends AsyncTask
{
#Override
protected void onPostExecute(Object result) {
dialog.dismiss();
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(Mwfa.this, "",
"Loading. Please wait...", true);
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... arg0) {
//your code
}
return null;
}
}
}
I would us a AsyncTask. Here is the structure of what should happen.
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(context, "", "Loading. Please wait...",
true);
}
#Override
protected EventWebservice doInBackground(Void... params) {
//call the webservice and return it
}
#Override
protected void onPostExecute(EventWebservice webservice) {
adapter = webservice.getAdapter(this);;
listView.setAdapter(adapter);
dialog.dismiss();
}
You need to read on unsynchronized ws calls and how to fill up data in a listview dynamically. Here is the code snippet below that works and will ensure that no mattter how much time the WS CAll takes there is no interruption on the GUI and the flow is smooth:
String wsResponse[];
public void sampleFunction()
{
progressDialog = ProgressDialog.show(this, "", "Getting backup list...");
new Thread() {
public void run() {
try {
//do the ws call and store the ws response in a string array
wsResponse=wsCall();
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
messageHandler.sendEmptyMessage(0);
// messageHandler.sendEmptyMessage(0);
}
}.start();
}
}
//inside the handler set the string array retrieved from the WS in sampleFunction to the adapter
private Handler messageHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
//here write the code to assign the string array to the adapter
}
};
Move your
listView.setAdapter(adapter);
progressDialog.dismiss();
adapter.notifyDataSetChanged();
into a Handler and call the method sendEmptyMessage() of Handler from the Thread.run() after you got the Adapter.
Consider this post for more information
Edit:
Your code should be look like something this.
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
//this is call the webservice to got filled adapter
adapter = new EventWebservice().getAdapter(this);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Where your Handler will update the list. But devA's answer is best way to do such jobs.