How to display view while doing a background process on android - android

I'm having a minor problem and I don't know how to do it.
I created a app, that pulls information through an xml web service.
The data get's parsed and inserted into a local sqlite database.
Everything works so far.
Due to the size of the data (that varies based on the pulled information) I intended to insert a loading screen with a progressbar and a spinner to notify the user that actions are taken.
Well let's say it, that it is planed to work this way.
My Problem is, that it is displayed, as soon as the work is done, not bevor.
This is how I've done it:
Handler phHandle = new Handler(){
#Override
public void handleMessage(Message msg){
int progress = msg.arg1;
pb.setProgress(progress);
}
};
class firstInitHandler implements Runnable{
private Handler phHandle;
public void setHandle(Handler h){
this.phHandle = h;
}
public void run(){
try {
firstInit i = new firstInit();
i.doInit(this.phHandle);
if(i.isResult())
i.doParse();
if(i.isData()){
i.doTasks();
i.doEquipment();
i.doUser();
i.doCompany();
i.doForms();
i.doSysconfig();
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
firstInitHandler h = new firstInitHandler();
h.setHandle(phHandle);
h.run();
This is part of a method.
Well it works so far.
The thread for processing the information is visible in task manager in the sdk.
I can also see the status messages on logcat that are created while the debug system works.
But the screen stays blank and only is displayed as soon as the task is done.
I'm a little bit confused and don't know where to start to have the waiting screen work.
I would welcome any help.
Chris

You can use AsyncTask fot this to work smoothly....
Inside your activity define the AsyncTask ....
then you can call the AsyncTask from onclick or inside onCreate in this way
new loading().execute();
The AsyncTask class will be as below.
The basic concept is to initialize the progress dialog in
onPerExecute().
Do the heavy stuff (non UI ) like parsing and all in
DoInBackground().
Then dismiss the dialog in onPostExecute().
you cannot do the UI changes in DoinBackGround, but you can do that
in OnPre / OnPostExecute().
the class is as follows.
private class loading extends AsyncTask'<'String, Integer, Boolean>
{
ProgressDialog dialog ;
#Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(result==true)
{
dialog.dismiss();
}
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog = new ProgressDialog(current.this);
dialog.setMessage("Loading...");
dialog.show();
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
#Override
protected Boolean doInBackground(String... params) {
// TODO Auto-generated method stub
try {
firstInit i = new firstInit();
i.doInit(this.phHandle);
if(i.isResult())
i.doParse();
if(i.isData()){
i.doTasks();
i.doEquipment();
i.doUser();
i.doCompany();
i.doForms();
i.doSysconfig();
}
} catch (NullPointerException e)
{
e.printStackTrace();
return false;
}
return true;
}
}

Have you tried looking at the Android Developers resources?
Here is the Dialog tutorial. A progress dialog example is shown on this page, or you could hop to the specific progress dialog section where it shows all the possible commands, usages, etc.
Hope this is what you need.

Related

How to show ProgressDialog across launching a new Activity?

Goal: Have a ProgressDialog which shows "Loading..." until next Activity is completely loaded and shown on screen.
Tried with ProgressDialog context and activity set to originating Activity. Also tried with getApplicationContext() and getParentContext(). Exceptions on the last two approaches. Need to do this as destination Activity is slow to render due to non-simple Layout file. (Cannot fix that right now due to organizational issues.) Turns out the destination Activity takes 1-2 seconds to OnCreate and then screen goes black for up to 5+ seconds then it paints. The rendering is just slow. Did review with Hierarchy Viewer and see lots of red balls but can't fix now.
Read up on some related but haven't found a fix. E.g. What's the difference between the various methods to get a Context?
E.g. both of these crash. Using the "this" of source Activity doesn't work either.
// Context parentContext = this.getParent().getBaseContext();
Context parentContext = this.getApplicationContext();
ProgressDialogMenuable theProgressDialog = new ProgressDialogMenuable(parentContext,this);
theProgressDialog.setTitle("yeeha");
theProgressDialog.setMessage("weewah");
theProgressDialog.setIndeterminate(true);
theProgressDialog.setCancelable(true);
theProgressDialog.show();
Also, oddly, nothing happens when I do this:
theProgressDialog.show();
ActivityHelper.changeActivity(this, v, InsMyHoldingsActivity.class, extraMap, -1, -1);
User clicks button to show next activity but the ProgressDialog conflicts with the Activity launch and nothing actually happens other than the button becoming yellow ontouch. Button below works. removing ProgressDialog creation and it works. No console messages logged. A little offputting to the developer for sure.
You can show a progress dialog like this -
Define this
private ProgressDialog pd = null;
in your activity class
Put this in your onCreate (Dont setContentView directly here)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.pd = ProgressDialog.show(this, "Fancy App",
"Loading...Please wait...", true, false);
// Start a new thread that will download all the data
new IAmABackgroundTask().execute();
}
// Background heavy lifting
class IAmABackgroundTask extends
AsyncTask<String, Integer, Boolean> {
#Override
protected void onPreExecute() {
// showDialog(AUTHORIZING_DIALOG);
}
#Override
protected void onPostExecute(Boolean result) {
// Pass the result data back to the main activity
ActivityName.this.data = result;
if (ActivityName.this.pd != null) {
ActivityName.this.pd.dismiss();
}
setContentView(R.layout.main);
}
#Override
protected Boolean doInBackground(String... params) {
//Do all your slow tasks here but dont set anything on UI
//ALL ui activities on the main thread
return true;
}
}
Also go through this :http://developer.android.com/training/improving-layouts/index.html for optimizing layout performance.
Also Use Traceview to look for bottlenecks
There is two ways to
First approach To use Async Task
If you are doing heavy tasks eg loading data from server or parsing xml in that case use AsynTask<> If you want to call ActivityB from ActivityA then
*step-1*create a AsyncTask class. write all background tasks inside doBackground() method and after completion of task you want to call an activity that code write inside onPostExecute() post execute method
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.view.View;
public class LoadingDataFromServer extends AsyncTask {
Context currentContext = null;
boolean isCancelled = false;
public LoadingDataFromServer(Context context) {
currentContext = context;
}
#Override
protected void onPreExecute() {
if (DashboardActivity.progressBarLayout != null) {
DashboardActivity.progressBarLayout.setVisibility(View.VISIBLE);
// Log.i(TAG,".....Now make progress bar visible.....");
}
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
// do background processing
try {
// do background tasks eg sever communication
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
// progressDialog.dismiss();
// call second Activity
Intent i = new Intent(currentContext, com.ActvityB.class);
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
isCancelled = true;
super.onCancelled();
}
}
step-2 In the activity fro where you want to jump to new activity (eg in ActivityA) call the execute() of AsynTask
new LoadingDataFromServer(context).execute(null);
Second approach
First show progress dialog.
create a thread to do all background tasks. when the thread completes the task then cancel the progress dialog and call the next activity
or
when thread complets the task then call next activity pass this object (progress dialog) and inside that new activity dismiss this dialog.
Here is my code that can help.
In this, I'm only posting the first method of AsyncTask i.e onPreExecute.
User_AsyncTask extends AsyncTask:
public class User_AsyncTask extends AsyncTask<String, String, String>
{
String response = "";
#Override
protected void onPreExecute()
{
try
{
if (progressDialog != null)
progressDialog.cancel();
}
catch (Exception e)
{
}
progressDialog = ProgressDialog.show(DisplayDetails.this, "", "Please wait...", true, true);
progressDialog.setCancelable(false);
progressDialog.show();
}

Asynctask Progress bar not displayed properly

I have a class in which i have to execute 3 long operations .And have to show the progress bar at the intervals 25%,50%,75% and 100%.
Since the operations use the UI thread , i cannot place them in the DoinBackground method()..
I am placing the opeartions in progressUpdate method
Code
package com.integrated.mpr;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.stat.correlation.Covariance;
import org.apache.commons.math.stat.correlation.PearsonsCorrelation;
import org.apache.commons.math.util.FastMath;
public class Logic extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
String x = "abc";
new loadSomeStuff().execute(x);
}
public class loadSomeStuff extends AsyncTask<String,Integer,String>{
ProgressDialog dialog;
protected void onPreExecute(){
dialog = new ProgressDialog(Logic.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMax(100);
dialog.show();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
publishProgress(25);
publishProgress(50);
publishProgress(75);
publishProgress(100);
return null;
}
protected void onProgressUpdate(Integer...progress){
if(progress[0]==25){
dialog.incrementProgressBy(25);
Log.d("now in ", "25 loop");
// do some long work in loop1
dialog.incrementProgressBy(25);
}
else if(progress[0]==25){
dialog.incrementProgressBy(25);
Log.d("now in ", "50 loop");
// do some long work in loop2
dialog.incrementProgressBy(25);
}
else if (progress[0] == 75){
dialog.incrementProgressBy(25);
// do some long work in loop3
}
else{
dialog.incrementProgressBy(25);
}
}
protected void onPostExecute(String result){
dialog.dismiss();
Intent openList = new Intent("com.integrated.mpr.SENSITIVELIST");
startActivity(openList);
}
}
}
Now , when i run this a blank screen appears , and the progress displays just for 100% .
How can i correct this?? please help
First of all you are making some BIG error.
onProgressUpdate is used to update the UI so you have not to do some long work on that method. All the long work you have to made it in doInBackground and when you finish a part of it you can call the onProgressUpdate to update the UI.
Also
Now , when i run this a blank screen appears , and the progress
displays just for 100%
That's because you are doing no work and your phone is fast :P
Try to put a Thread.sleep(1000) betweek each call of onProgressUpdate :)
Than you will replace the sleep with real work!
You should not use the ui thread to compute long operation. Your long operations should be executed in doinbackground which will execute them in a different thread.
Edit : I think the problem is that you really want to work with the ui thread for whatever reason you have. If that's the case, maybe a handler would be more suitable.
http://developer.android.com/reference/android/os/Handler.html

Regarding AsyncTask for creating a loading screen

I am on a dilemma on how to achieve "Creating a loading screen" on a AsyncTask mainly using progressDialog.
What I am doing is that I have a method which takes no inputs and just shows a textview.
private class DownloadFilesTask extends AsyncTask {
So what my method does is simply like 1 + 1 = 2 but in a more complex way of storing a giganormous string which then get shown on a textview.
So my question is how do I achieve the result of a progress dialog before this long load?
Android already has a progress dialog class built-in. I'd recommend using that, unless there's something about it that doesn't suit your needs.
private progressDialog pd;
public void runMethod(){
new doStuuff.execute();
}
private Class doStuff extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
//Everything in your code except for anything that is xml or relates with any view. Mostly calculations
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
//Your main background view code ends up falling here
pd.dismiss();
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
//Your optional view and where it starts
pd = ProgressDialog.show(View_Book_As_Whole.this, "Loading", "Please wait...");
}
}
I was being too noob not to understand the concept but it is relatively easy once you understand it. onPreExecute() means that it runs before anything and it takes priority first then goes to doInBackground(), and then onPostExecute() it runs the final task. This all works in the background of the UI.

How to execute some code in Android UI thread async?

I'm new to Android development. I've be working on Swing and SWT for several years. Both Swing and SWT has a stratage to execute code in UI thread sync and async. The typical usage is doing some time-consume staff in one thread then display the result in UI thread async.
So my question is, is there similiar stratage in Android? Here is my code. Parameter runnable is some time-consume code. This method will display a waiting dialog during the execution then EXPECT to show a Toast after it is finished. But the Toast need to be show in UI thread. So how to do that?
public static void showWaitingDialog(final Activity parent, final Runnable runnable, String msg) {
if (StringUtils.isEmpty(msg)) {
msg = "processing...";
}
final ProgressDialog waitingDialog = ProgressDialog.show(parent, "Please Wait...", msg, true);
// execute in a new thread instead of UI thread
ThreadPoolUtil.execute(new Runnable() {
public void run() {
try {
// some time-consume operation
runnable.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
waitingDialog.dismiss();
}
// TODO: How to display a Toast message here? execute some code in UI Thread.
}
});
}
And is there some words about Android UI system? Such as is it Thread-Safe, how thread works together and so on. Many Thanks!
There are several ways for doing that,
AsyncTask -
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers. Example for using AsyncTask
Service -
A Service is an application component representing either an
application's desire to perform a longer-running operation while not
interacting with the user or to supply functionality for other
applications to use. Example for Using Service.
IntentService -
IntentService is a base class for Services that handle asynchronous
requests (expressed as Intents) on demand. Clients send requests
through startService(Intent) calls; the service is started as needed,
handles each Intent in turn using a worker thread, and stops itself
when it runs out of work. Example for using IntentService.
You can use AsyncTask like this.
To call AsyncTask
new getAsynctask().execute("");
and here is the class for geting result.
class getAsynctask extends AsyncTask<String, Long, Integer> {
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(Pass.this, null, "Please wait...");
}
protected Integer doInBackground(String... params) {
try {
// do your coding
return null;
} catch (Exception e) {
return null;
}
}
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
try {
if (loading != null && loading.isShowing())
loading.dismiss();
} catch (Throwable t) {
Log.v("this is praki", "loading.dismiss() problem", t);
}
}
}
Whenever you are working with Separate thread which is not your UI thread the best way is to use Handler. Whenever you want to intimate user from your Thread, suppose a progress then send a message to Handler to so. Inside Handler you can handle message and write a code snippet to Change anything on UI. This is the preferred way for Android. see these link1 , link2 & link3
You use this AsynTask as a inner class of your activity. In do in background do the time consuming task you want to do and then in on postexecute you can show the text message.
call this from your main activity
initTask = new InitTask();
initTask.execute(this);
protected class InitTask extends AsyncTask<Context, Integer, String> {
#Override
protected String doInBackground(Context... params) {
// Do the time comsuming task here
return "COMPLETE!";
}
// -- gets called just before thread begins
#Override
protected void onPreExecute() {
super.onPreExecute();
}
// -- called from the publish progress
// -- notice that the datatype of the second param gets passed to this
// method
#Override
protected void onProgressUpdate(Integer... values) {
}
// -- called if the cancel button is pressed
#Override
protected void onCancelled() {
super.onCancelled();
}
// -- called as soon as doInBackground method completes
// -- notice that the third param gets passed to this method
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Show the toast message here
}
}
Use a handler:
static final int SHOW_TOAST = 0;
public static void showWaitingDialog(final Activity parent, final Runnable runnable, String msg) {
if (StringUtils.isEmpty(msg)) {
msg = "processing...";
}
final ProgressDialog waitingDialog = ProgressDialog.show(parent, "Please Wait...", msg, true);
// execute in a new thread instead of UI thread
ThreadPoolUtil.execute(new Runnable() {
public void run() {
try {
// some time-consume operation
runnable.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
waitingDialog.dismiss();
}
handler.sendMessage(handler.obtainMessage(SHOW_TOAST));
}
});
}
public Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_TOAST:
//Toast here
break;
}
}
};
The Painless threading article from the android developer resources provides different alternatives depending on the specific SDK version.

Android AsyncTask issue

I've developed an application that takes content from the internet and shows it accordingly on the device's screen . The program works just fine , a little bit slow . It takes about 3-4 seconds to load and display the content . I would like to put all the code that fetches the content and displays it in a background thread and while the program is doing those functions , I would like to display a progress dialog. Could you help me do this ? I would like especially to learn how to put the code in a background thread.
MY CODE
public class Activity1 extends Activity
{
private ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AsyncTask<Integer, Integer, Boolean>()
{
ProgressDialog progressDialog;
#Override
protected void onPreExecute()
{
/*
* This is executed on UI thread before doInBackground(). It is
* the perfect place to show the progress dialog.
*/
progressDialog = ProgressDialog.show(Activity1.this, "",
"Loading...");
}
#Override
protected Boolean doInBackground(Integer... params)
{
if (params == null)
{
return false;
}
try
{
/*
* This is run on a background thread, so we can sleep here
* or do whatever we want without blocking UI thread. A more
* advanced use would download chunks of fixed size and call
* publishProgress();
*/
Thread.sleep(params[0]);
// HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME
}
catch (Exception e)
{
Log.e("tag", e.getMessage());
/*
* The task failed
*/
return false;
}
/*
* The task succeeded
*/
return true;
}
#Override
protected void onPostExecute(Boolean result)
{
progressDialog.dismiss();
/*
* Update here your view objects with content from download. It
* is save to dismiss dialogs, update views, etc., since we are
* working on UI thread.
*/
AlertDialog.Builder b = new AlertDialog.Builder(Activity1.this);
b.setTitle(android.R.string.dialog_alert_title);
if (result)
{
b.setMessage("Download succeeded");
}
else
{
b.setMessage("Download failed");
}
b.setPositiveButton(getString(android.R.string.ok),
new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dlg, int arg1)
{
dlg.dismiss();
}
});
b.create().show();
}
}.execute(2000);
new Thread()
{
#Override
public void run()
{
// dismiss the progressdialog
progressDialog.dismiss();
}
}.start();
}
}
The app crashes , NullPointerException among other stuff . Could you help me ? thanks.
You code is fine, except for the last Thread, which, beside being useless, is the reason your app crashes : when the thread is started, the progressDialog is not initialized yet.
Otherwise, this should work like a charm.
Edit
One more thing: giving null as a onClickListener for the positive or negative button simply dismiss the dialog (which is what you do), so
b.setPositiveButton(android.R.string.ok, null);
is equivalent, only shorter.
You do the downloading in the doInBackground() method. Now you need to override onProgressUpdate() method where you'll do .setProgress() to your progressbar. onProgressUpdate() runs on ui-thread. Use .publishProgress() method from where (from background thread i.e doInBackground() method) you'll make a call to onProgressUpdate().
I hope this idea will help you.
http://developer.android.com/reference/android/os/AsyncTask.html#publishProgress(Progress...)

Categories

Resources