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.
Related
I am creating an app where user can upload images, I am uploading images one after another using retrofit. Right now I am running a for loop for it, but it is not a good way to do it. I cannot use service because I need progress dialog as well on main screen to let user know upload is happening. Is there a way to maintain some kind of queue to handle this?
You can use the AsyncTask and Retrofit to do it it can be done with the retrofit alone but as I have already done it with AsyncTask have a look.
public class AsyncBulkUpload extends AsyncTask<Boolean, Integer, Boolean> {
private ApiInterface mApiInterface;
private Call<ResponseBody> mResponseBodyCall;
private Response<ResponseBody> mResponseBody;
private RequestBody mRequestBody;
private Service mService;
private Bitmap mItemBitmap;
public int mTotalCount = 0;
public AsyncBulkUpload(Service service) {
mService=service;
mApiInterface = ApiClient.getClient(mService.getApplicationContext()).create(ApiInterface.class);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mTotalCount = sClosetList.size();
//Show you dialog
}
#Override
protected Boolean doInBackground(Boolean... itsRetry) {
/**
*Check if its retry or not
* if yes don't get the placeholder ids.
* or else hit and get place holder ids
*/
//Run your loop here.
return upload();
}
private Boolean upload() {
if (isCancelled())
return false;
if (sClosetList.size() > 0) {
//Item image
try {
mItemBitmap = Glide.with(mService.getApplicationContext())
.load(sClosetList.get(0).mItemImage)
.asBitmap()
.into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.get();
} catch (InterruptedException e) {
//Coudnt get the image so cant go further
LogPrint.printError("WHILE GETTING BITMPAP");
return false;
} catch (ExecutionException e) {
//Coudnt get the image so cant go further
LogPrint.printError("WHILE GETTING BITMPAP");
return false;
}
FormBody.Builder bodyBuilder = new FormBody.Builder();
bodyBuilder.add("image", mItemBitmap);
/**
*Label image can or can not be available
*/
mRequestBody = bodyBuilder.build();
mResponseBodyCall = mApiInterface.uploadProducts(mRequestBody);
try {
mResponseBody = mResponseBodyCall.execute();
} catch (IOException e) {
e.printStackTrace();
return false;
}
if (!mResponseBody.isSuccessful()) {
/**
*Some server error try again
*/
return false;
}
}
return true;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//Update your progressbar
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
//Dismiss the dialog
if (aBoolean) {
Toast.makeText(mService, R.string.uploaded_successful, Toast.LENGTH_LONG).show();
}
}
}
I'm executing the practically identical code (besides the return statement) in onCreate() in two different ways:
once in a Thread (that works)
and once in an AsyncTask
Somehow the Exception thrown in the AsyncTask can't even be debugged... do you have an idea why this code doesn't work in the AsyncTask and why I can't debug de Exception? (It is not present as a variable)
public class TrainingProgressActivity extends ActivityTemplate {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_training_progress);
// the not working AsyncTask variant
new ProgressGetterTask().execute("");
// the working Thread variant
new Thread(new Runnable() {
public void run() {
try {
RestTemplate restTemplate = RestTemplateFactory.createRestTemplate();
FeatureSetCollectionProgress i = restTemplate.postForObject(URLHelper.BASE_PATH+"training/progress", getDevice(), FeatureSetCollectionProgress.class);
System.out.println(i.getMobilityProgress().get(0).getTransportationMeanType().toString());
} catch(Exception e) {
System.out.println("ex");
e.printStackTrace();
}
}}).start();
}
/**
* ProgressGetterTask. (not working ???)
*/
private class ProgressGetterTask extends AsyncTask<String, FeatureSetCollectionProgress, FeatureSetCollectionProgress> {
protected FeatureSetCollectionProgress doInBackground(String... urls) {
try {
RestTemplate restTemplate = RestTemplateFactory.createRestTemplate();
return restTemplate.postForObject(URLHelper.BASE_PATH+"training/progress", getDevice(), FeatureSetCollectionProgress.class);
} catch(Exception e) {
e.printStackTrace();
return null; // setting breakpoint here, 'e' cannot be resolved to a variable.
}
}
protected void onPostExecute(FeatureSetCollectionProgress featureSetCollectionProgress) {
if(featureSetCollectionProgress!=null) {
} else {
}
}
}
}
In my app I performing loading data from web and then displaying it to user. Before loading data app shows progress dialog. I have problem if user locks phone in the middle of loading operation, or server is overloaded and can't respond in time my application freezes, because it doesn't dismiss progress dialog, or in some cases it crashes because lack on needed data.
If some error happened while loading data I want show some dialog to user to let him know about error and ask him should application repeat last request. I tried to use AlertDialog for it, but I haven't succeed.
Here is code of one activity (There is no progress dialog here, but it demonstrates how I loading data):
#EActivity(R.layout.layout_splash)
#RoboGuice
public class SplashScreenActivity extends Activity {
#Inject
private AvtopoiskParserImpl parser;
#Bean
BrandsAndRegionsHolder brandsAndRegionsHolder;
#ViewById(R.id.splash_progress)
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadData();
}
#Background
protected void loadData() {
publishProgress(10);
LinkedHashMap<String, Integer> brands = null;
try {
brands = parser.getBrands();
} catch (IOException e) {
Log.e(e.getMessage());
}
publishProgress(50);
LinkedHashMap<String, Integer> regions = null;
try {
regions = parser.getRegions();
} catch (IOException e) {
Log.e(e.getMessage());
}
publishProgress(70);
populateData(brands, regions);
}
#UiThread
protected void populateData(LinkedHashMap<String, Integer> brands, LinkedHashMap<String, Integer> regions) {
Intent intent = new Intent(SplashScreenActivity.this, SearchActivity_.class);
brandsAndRegionsHolder.brandsMap = brands;
brandsAndRegionsHolder.regionsMap = regions;
publishProgress(100);
startActivity(intent);
finish();
}
#UiThread
void publishProgress(int progress) {
progressBar.setProgress(progress);
}
}
parser.getBrands() and parser.getRegions() are loading data from the web.
I want to do something like this:
boolean repeatRequest = true;
while (repeatRequest) {
try {
brands = parser.getBrands();
repeatRequest = false;
} catch (IOException e) {
Log.e(e.getMessage());
repeatRequest = showErrorDialog();
}
}
But I didn't manage to do so because this code executes in background thread, but dialog should be shown in UI thread.
I believe that it should be standard approach of doing so, but didn't manage to find it.
Any ides how can I implement this?
The best way is to use AsyncTask.
private class LoadDataTask extends AsyncTask<Void, Integer, Object> {
private ProgressDialog mProgress;
protected Object doInBackground(Void... params) {
// This method runs in background
Object result = null;
try {
result = parser.parse();
} catch (Exception e) {
result = e.getMessage();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
// This method runs in UI thread
mProgress.setProgress(progress[0]);
}
protected void onPreExecute() {
// This method runs in UI thread
mProgress = new ProgressDialog(context);
mProgress.show();
}
protected void onPostExecute(Object result) {
// This method runs in UI thread
mProgress.dismiss();
if (result instance of String) {
// Here you can launch AlertDialog with error message and proposal to retry
showErrorDialog((String) result);
} else {
populateData(result);
}
}
}
Main Class:
public class ProgressIndicator {
static ProgressIndicator instance;
Context context;
public static ProgressIndicator getInstance() {
if (instance == null) {
instance = new ProgressIndicator();
}
return instance;
}
private ProgressIndicator() {
}
IndicatorThread sd;
public void showIndicator(Activity activity, String title, String message, boolean flag) {
sd = new IndicatorThread(activity, title, message, flag);
sd.start();
}
public void dismissIndicator(Activity activity) throws InterruptedException{
sd.dismiss();
// sd.join();
}
private static class IndicatorThread extends Thread {
private static final Message listener = null;
private static String mTitle;
private static String mText;
private Activity mActivity;
private boolean mflag;
private ProgressDialog mDialog;
protected boolean dismiss;
IndicatorThread(Activity activity, String title, String text, boolean flag) {
super();
IndicatorThread.mText = text;
IndicatorThread.mTitle = title;
this.mActivity = activity;
this.mflag = flag;
if (mDialog == null) {
mDialog = new ProgressDialog(mActivity);
mDialog.setTitle(mTitle);
mDialog.setMessage(mText);
mDialog.setIndeterminate(true);
mDialog.setCancelable(true);
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
if(mflag == true){
mDialog.setButton("Cancel", listener);
mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface arg0) {
mDialog.dismiss();
interrupt();
}
});
}
}
mDialog.show();
mDialog.getWindow().setLayout(160, 350);
mDialog.getWindow().setGravity(0);
}
public void dismiss() {
dismiss = true;
mDialog.dismiss();
System.out.println("notifying..."+dismiss);
synchronized (this) {
notifyAll();
}
}
#Override
public void run() {
System.out.println("Running..."+dismiss);
while (!dismiss) {
System.out.println("waiting..."+!dismiss);
synchronized (this) {
try {
wait();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
System.out.println("Quitting...");
}
}
}
Call from AppController class:
private ProgressIndicator progressInstance = null;
public void showWaitingAnimation(Activity parent) {
progressInstance.showIndicator(AppController.getInstance().currentActivity, "" , "", false);
}
Test Class:
public class ProgressIndicatorTest extends
ActivityInstrumentationTestCase2<MyTestActivity> {
private Solo solo;
private ProgressIndicator progressIndicatorInstance;
public ProgressIndicatorTest() {
super("com.test.activity",
MyTestActivity.class);
}
protected void setUp() throws Exception {
AppController.getInstance().startApp(getActivity());
solo = new Solo(getInstrumentation(), getActivity());
progressIndicatorInstance = ProgressIndicator.getInstance();
}
protected void tearDown() throws Exception {
try {
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
public void testGetInstance() {
try {
ProgressIndicator instance = ProgressIndicator.getInstance();
assertNotNull(instance);
} catch (Exception e) {
fail("Creation of ExceptionDetails get instance failed!");
}
}
public void testShowIndicator() {
Log.d("testCase Name:-", "testShowIndicator");
ProgressIndicator progressInstance = ProgressIndicator.getInstance() ;
progressInstance.showIndicator(AppController.getInstance().getCurrentActivity(), "" , "", false);
//AppController.getInstance().showWaitingAnimation(AppController.getInstance().getCurrentActivity());
solo.waitForDialogToClose(8000);
try {
progressInstance.dismissIndicator(AppController.getInstance().getCurrentActivity());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void testDismissIndicator() {
Log.d("testCase Name:-", "testDismissIndicator");
ProgressIndicator progressInstance = ProgressIndicator.getInstance() ;
progressInstance.showIndicator(AppController.getInstance().getCurrentActivity(), "" , "", false);
solo.waitForDialogToClose(2000);
try {
progressInstance.dismissIndicator(AppController.getInstance().getCurrentActivity());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//AppController.getInstance().showAppTerminationDialog("", AppController.getInstance().getCurrentActivity());
}
}
While running the project the dialog is visible & working properly. But while running the test case only a black screen is visible, no dialog is getting displayed (after using solo.waitForDialogToClose(8000); problem is there). No error or exception is getting thrown and the test cases are getting passed in Android Junit test. If anyone has any idea how to display this progress dialog in case of robotium test, Please share.
In my case I can successfully display progress dialogs.
I simply used
boolean showProgressBar = false;
showProgressBar = solo.waitForText("Verifying and Saving Credentials...", 1, 3000);
I hope it should also work for you.. :)
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();
}
}
}