Here is a few bit of code:
public class ShowDialog extends Thread {
private static String mTitle="Please wait";
private static String mText="Loading...";
private Activity mActivity;
private ProgressDialog mDialog;
ShowDialog(Activity activity) {
this(activity, mTitle, mText);
}
ShowDialog(Activity activity, String title) {
this(activity, title, mText);
}
ShowDialog(Activity activity, String title, String text) {
super();
mText=text;
mTitle=title;
mActivity=activity;
if (mDialog == null) {
mDialog = new ProgressDialog(mActivity);
mDialog.setTitle(mTitle);
mDialog.setMessage(mText);
mDialog.setIndeterminate(true);
mDialog.setCancelable(true);
mDialog.setOnCancelListener(
new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface arg0) {
mDialog.dismiss();
interrupt();
}
});
}
}
public void run() {
mDialog.show();
while(!isInterrupted())
mDialog.dismiss();
mDialog=null;
}
}
And in my main activity:
ShowDialog show = new ShowDialog(this, "Please wait!","Loading badly...");
show.start();
SystemClock.sleep(2000);
show.interrupt();
I know I might use an async task and all the stuff but that is not what I want. Replace the SystemClock.sleep by anything that takes some time. The idea is to execute the code between start and interrupt in the UI thread and make a seperate thread handling the ProgressDialog.
What's wrong with my thread ?
Thanks a lot!
To wait for a Thread to complete, you should use the Thread.join() method. But now I see you're not wanting to wait for it to complete, but you need to control when it completes. Still, you want to avoid interrupting threads in this fashion.
In your ShowDialog class, add a dismiss() method that you can call from your main, instead of interrupt(). Also add a boolean dismiss = false instance variable. In dismiss(), add dismiss = true, then notify();. In run(), replace your constant while() loop (was running constantly, and very inefficient) with while(!dismiss){wait()}. You will still need to add synchronization blocks and exception handling, but this should get you off to a good start.
Here is a generic-Java (non-android) simplified example:
public static class ShowDialog extends Thread{
protected boolean dismiss;
public void dismiss(){
dismiss = true;
synchronized(this){
notifyAll();
}
}
#Override
public void run(){
System.out.println("Running...");
// Show your dialog here.
while(!dismiss){
synchronized(this){
try{
wait();
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
}
System.out.println("Quitting...");
// Dismiss your dialog here.
}
}
public static void main(String[] args) throws Exception{
ShowDialog sd = new ShowDialog();
sd.start();
Thread.sleep(2000);
sd.dismiss();
}
You mentioned you didn't want to use AsyncTask, but I would still reconsider. (What are your reasons against it?)
Related
I use an async task to upload an image and get some results.
While uploading the image I see a progress dialog, written in onPreExecute() method like this:
protected void onPreExecute() {
uploadingDialog = new ProgressDialog(MyActivity.this);
uploadingDialog.setMessage("uploading");
uploadingDialog.setCancelable(true);
uploadingDialog.show();
}
Ok when I press the back button, obviously the dialog disappears because of the setCancelable(true).
But (obviously) the async task doesn't stop.
So how can I fix this? I want to cancel both dialog and async task when I press the back button. Any ideas?
From SDK:
Cancelling a task
A task can be cancelled at any time by invoking cancel(boolean).
Invoking this method will cause subsequent calls to isCancelled()
to return true.
After invoking this method, onCancelled(Object), instead of
onPostExecute(Object) will be invoked after doInBackground(Object[]) returns.
To ensure that a task is cancelled as quickly as possible,
you should always check the return value of isCancelled() periodically from
doInBackground(Object[]), if possible (inside a loop for instance.)
So your code is right for dialog listener:
uploadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
myTask.cancel(true);
//finish();
}
});
Now, as I have mentioned earlier from SDK, you have to check whether the task is cancelled or not, for that you have to check isCancelled() inside the onPreExecute() method.
For example:
if (isCancelled())
break;
else
{
// do your work here
}
FOUND THE SOLUTION:
I added an action listener before uploadingDialog.show() like this:
uploadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){
public void onCancel(DialogInterface dialog) {
myTask.cancel(true);
//finish();
}
});
That way when I press the back button, the above OnCancelListener cancels both dialog and task. Also you can add finish() if you want to finish the whole activity on back pressed. Remember to declare your async task as a variable like this:
MyAsyncTask myTask=null;
and execute your async task like this:
myTask = new MyAsyncTask();
myTask.execute();
I spent a while figuring this out, all I wanted was a simple example of how to do it, so I thought I'd post how I did it. This is some code that updates a library and has a progress dialog showing how many books have been updated and cancels when a user dismisses the dialog:
private class UpdateLibrary extends AsyncTask<Void, Integer, Boolean>{
private ProgressDialog dialog = new ProgressDialog(Library.this);
private int total = Library.instance.appState.getAvailableText().length;
private int count = 0;
//Used as handler to cancel task if back button is pressed
private AsyncTask<Void, Integer, Boolean> updateTask = null;
#Override
protected void onPreExecute(){
updateTask = this;
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setOnDismissListener(new OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
updateTask.cancel(true);
}
});
dialog.setMessage("Updating Library...");
dialog.setMax(total);
dialog.show();
}
#Override
protected Boolean doInBackground(Void... arg0) {
for (int i = 0; i < appState.getAvailableText().length;i++){
if(isCancelled()){
break;
}
//Do your updating stuff here
}
}
#Override
protected void onProgressUpdate(Integer... progress){
count += progress[0];
dialog.setProgress(count);
}
#Override
protected void onPostExecute(Boolean finished){
dialog.dismiss();
if (finished)
DialogHelper.showMessage(Str.TEXT_UPDATELIBRARY, Str.TEXT_UPDATECOMPLETED, Library.instance);
else
DialogHelper.showMessage(Str.TEXT_UPDATELIBRARY,Str.TEXT_NOUPDATE , Library.instance);
}
}
create some member variables in your activity like
YourAsyncTask mTask;
Dialog mDialog;
use these for your dialog and task;
in onPause() simply call
if(mTask!=null) mTask.cancel();
if(mDialog!=null) mDialog.dismiss();
I would like to improve the code. When you canel the aSyncTask the onCancelled() (callback method of aSyncTask) gets automatically called, and there you can hide your progressBarDialog.
You can include this code as well:
public class information extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... arg0) {
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
this.cancel(true);
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onCancelled() {
Toast.makeText(getApplicationContext(), "asynctack cancelled.....", Toast.LENGTH_SHORT).show();
dialog.hide(); /*hide the progressbar dialog here...*/
super.onCancelled();
}
}
Most of the time that I use AsyncTask my business logic is on a separated business class instead of being on the UI. In that case, I couldn't have a loop at doInBackground(). An example would be a synchronization process that consumes services and persist data one after another.
I end up handing on my task to the business object so it can handle cancelation. My setup is like this:
public abstract class MyActivity extends Activity {
private Task mTask;
private Business mBusiness;
public void startTask() {
if (mTask != null) {
mTask.cancel(true);
}
mTask = new mTask();
mTask.execute();
}
}
protected class Task extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onCancelled() {
super.onCancelled();
mTask.cancel(true);
// ask if user wants to try again
}
#Override
protected Boolean doInBackground(Void... params) {
return mBusiness.synchronize(this);
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
mTask = null;
if (result) {
// done!
}
else {
// ask if user wants to try again
}
}
}
public class Business {
public boolean synchronize(AsyncTask<?, ?, ?> task) {
boolean response = false;
response = loadStuff(task);
if (response)
response = loadMoreStuff(task);
return response;
}
private boolean loadStuff(AsyncTask<?, ?, ?> task) {
if (task != null && task.isCancelled()) return false;
// load stuff
return true;
}
}
I had a similar problem - essentially I was getting a NPE in an async task after the user had destroyed the activity. After researching the problem on Stack Overflow, I adopted the following solution:
volatile boolean running;
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
running=true;
...
}
public void onDestroy() {
super.onDestroy();
running=false;
...
}
Then, I check "if running" periodically in my async code. I have stress tested this and I am now unable to "break" my activity. This works perfectly and has the advantage of being simpler than some of the solutions I have seen on SO.
You can just ask for cancellation but not really terminate it. See this answer.
How to cancel AsyncTask
Full answer is here - Android AsyncTask Example
AsyncTask provides a better cancellation strategy, to terminate currently running task.
cancel(boolean mayInterruptIfitRunning)
myTask.cancel(false)- It makes isCancelled returns true. Helps to cancel the task.
myTask.cancel(true) – It also makes isCancelled() returns true, interrupt the background thread and relieves resources .
It is considered as an arrogant way, If there is any thread.sleep() method performing in background thread, cancel(true) will interrupt background thread at that time. But cancel(false) will wait for it and cancel task when that method completes.
If you invoke cancel() and doInBackground() hasn’t begun execute yet. onCancelled() will invoke.
After invoking cancel(…) you should check value returned by isCancelled() on doInbackground() periodically. just like shown below.
protected Object doInBackground(Params… params) {
while (condition)
{
...
if (isCancelled())
break;
}
return null;
}
I have created IntentService class and performing asyncTask but getting exception when onPreExecute() is called at this code line pDialog.show();
AsyncHandlerService Class ---
public class AsyncHandlerService extends IntentService{
ProgressDialog pDialog;
HttpPost post;
HttpResponse response;
Context ctx;
public AsyncHandlerService() {
super("AsyncHandlerService");
ctx = this;
}
#Override
protected void onHandleIntent(Intent intent) {
new LoadDeviceInfo().execute();
}
class LoadDeviceInfo extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ctx);
pDialog.setMessage("Updating device info...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show(); //Exception here..
}
protected String doInBackground(String... args) {
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
}
UPDATE:
I am calling the IntentService in the broadcast receiver that has the intent filter of android.intent.action.PACKAGE_REPLACED defined in android manifest. The code ---
public class OnUpgradeBroadcastReceiver extends BroadcastReceiver {
Context activity;
#Override
public void onReceive(final Context context, final Intent intent) {
activity = context;
Intent msgIntent = new Intent(activity, AsyncHandlerService.class);
activity.startService(msgIntent);
}
}
Error Log:
com.testapp.main fatal error : Unable to add window --
token null is not for an application
android.view.WindowManager$BadTokenException: Unable to add window --
token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:588)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
at android.view.WindowManagerImpl$CompatModeWrapper.
addView(WindowManagerImpl.java:149)
at android.app.Dialog.show(Dialog.java:277)
at com.testapp.main.AsyncHandlerService$LoadDeviceInfo.
onPreExecute(AsyncHandlerService.java:62)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
at android.os.AsyncTask.execute(AsyncTask.java:534)
First, IntentService already uses a background thread. You do not need another background thread. Do the work that needs to be done in the background in onHandleIntent().
Second, a Service cannot display a Dialog. Instead, let the UI layer of your app know that the work was done via a message on an event bus (e.g., LocalBroadcastManager, greenrobot's EventBus, Square's Otto). If the UI layer does not handle the event, your service can raise a Notification or otherwise let the user know about the work that was done, if that is needed.
Service isn't a UI thread.
Since you try to display a ProgressDialog from a service context, it can't be completed.
Try this solution:
https://stackoverflow.com/a/4369755/1405268
If for whatever reason you really really really want to use an AsyncTask (e.g. you've set up your framework to use AsyncTask to make calls to some web api) you can always use wait/notify such as:
public class GetCacheIntentService extends DebuggableIntentService implements ApiAsyncTask.Callback {
private static final String ACTION_GET_CACHE = "action.GET_CACHE";
private static final String EXTRA_INT_START = "extras.START";
private static final String EXTRA_INT_LIMIT = "extras.LIMIT";
private static final int API_GET_CACHE = 0;
private final Object mApiCallLock = new Object();
private GetCacheResponse getCacheResponse;
public GetCacheIntentService() {
super("GetCacheIntentService");
setIntentRedelivery(true);
}
public static void startServiceActionGetCache(Context context, int start, int limit) {
Intent intent = new Intent(context, GetCacheIntentService.class);
intent.setAction(ACTION_GET_CACHE);
intent.putExtra(EXTRA_INT_START, start);
intent.putExtra(EXTRA_INT_LIMIT, limit);
context.startService(intent);
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent == null) {
return;
}
String action = intent.getAction();
if (ACTION_GET_CACHE.equals(action)) {
int start = intent.getIntExtra(EXTRA_INT_START, 0);
int limit = intent.getIntExtra(EXTRA_INT_LIMIT, 100);
getCache(start, limit);
}
}
private void getCache(int start, int limit) {
GetCacheTask task = new GetCacheTask(this, API_GET_CACHE);
task.setStart(start);
task.setLimit(limit);
task.execute();
synchronized (mApiCallLock) {
try {
mApiCallLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
processResponse(mGetCacheResponse);
}
public void processResponse(GetCacheResponse response) {
// do something
}
#Override
public void onRequestFailed(int id, ApiResponse apiResponse) {
synchronized (mApiCallLock) {
switch (id) {
case API_GET_CACHE:
break;
}
mApiCallLock.notify();
}
}
#Override
public void onRequestSuccess(int id, ApiResponse response) {
synchronized (mApiCallLock) {
switch (id) {
case API_GET_CACHE:
mGetCacheResponse = (GetCacheResponse) response;
break;
}
mApiCallLock.notify();
}
}
}
this is quite ugly though :(
Not a good practise to call Asynctask from an Intent service. If you need to do spin other thread from IntentService consider using Executor.
ExecutorService es = Executors.newFixedThreadPool(5);
es.execute(new Runnable() {
#Override
public void run() {
}
});
es.execute(new Runnable() {
#Override
public void run() {
}
});
es.shutdown();
es.awaitTermination(1, TimeUnit.HOURS);
It is not a good practice to use AsyncTask inside IntentService sub-classes or even JobIntentService sub-classes. In the case of JobIntentServices it causes crash too.
I have an activity that popup instructions the first time the app runs ( In a DialogFragment).
I want to stop the execution of code while user don't dismiss the Dialog.
Is it posible to do it???
EDIT:
I try to use CountDownLatch but it is freezing my UI, and the Dialog is not showing.
Activity :
private CountDownLatch startSignal;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// open tutorial if need
startSignal = new CountDownLatch(1);
TutorialDialog tutoDial = new TutorialDialog();
tutoDial.show(getSupportFragmentManager(), "tuto");
try {
toast("aguardando");
startSignal.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Dialog ( I just put the needed methods) :
public class TutorialDialog extends DialogFragment {
private final String TAG = getClass().getSimpleName();
MapActivity parentActivity;
SharedPreferences preferences;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
parentActivity = ((MapActivity) activity);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// setStyle(DialogFragment.STYLE_NORMAL, 0);
AlertDialog.Builder principal = new AlertDialog.Builder(getActivity());
principal.setInverseBackgroundForced(true);
// principal.setTitle(R.string.report);
View view = getActivity().getLayoutInflater().inflate(
R.layout.tutorial, null);
TextView ok = (TextView)view.findViewById(R.id.ok);
ok.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
parentActivity.resumeCode();
dismiss();
}
});
AlertDialog ad = principal.create();
return ad;
}
}
And in the Activity, the method resumeCode():
public void resumeCode(){
startSignal.countDown();
toast("whats next");
}
EDIT 2: I implement it several times. My last implementation should be the one, but it still don't work. I will try to explain how it goes.
mainActivity ( Main thread) launch the dialogFragment:
TutorialDialog tutoDial = new TutorialDialog();
tutoDial.setCancelable(true);
tutoDial.show(getSupportFragmentManager(), "tuto");
Then, in another thread, I run await() in onPreExecute():
public class GetPlaces extends AsyncTask> {
private ProgressDialog dialog;
// I put it public so that I can reach it from the DialogFragment
public static CountDownLatch startSignal = new CountDownLatch(1);
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
startSignal.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dialog = new ProgressDialog(context);
dialog.setCancelable(false);
dialog.setMessage(context.getString(R.string.loading));
dialog.isIndeterminate();
dialog.setProgressStyle(R.style.dialogInput);
dialog.show();
}
This way, it should not run before the startSignal variable reach 0
Then, In my FragmentDialog, when the dialog dismiss, I run :
noTuto.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// DISMISS DIALOG
startSignal.countDown();
dismiss();
}
});
So in theory, it should work, but in the ugly reality, my FragmentDialog freeze...
What I'm sure :
1 - there is no startSignal.await(); in mainActivity that should freeze UI anymore
2 - The startSignal variable is define in another thread:
public class GetPlaces extends AsyncTask<Void, Void, ArrayList<Place>>
so, if anything freeze, it should be this thread, but I don't understand why my dialog is the one which is freezing. Right now, my dialog does not receive clicks anymore...
Use CountDownLatch startSignal = new CountDownLatch(1);
Your code will usually be executed in user thread. Make your user thread code startSignal.await(); so that it can pause its execution.
Your DialogFragment will be executed in UI thread. Make your UI thread code startSignal.countDown(), to resume your user thread code execution.
Is there a preferred way to show 'loading' animations in Android? Currently I'm showing Dialog with the text "Loading..." for long running processes. It's tricky to get a .gif to work for this, so I'm wondering if this is a problem that has been solved before, and if so, how?
In my apps, I typically use a ProgressDialog to show a spinning "Loading..." message. There are fancier/prettier ways, but this is a quick and easy built-in solution.
ProgressDialog progressDialog = ProgressDialog.show(Activity.this, "",
"Loading...");
...Do some work...
progressDialog.dismiss();
progressDialog = null;
If you have a static Utilities class to generate things like Alerts and Dialogs, here are 2 nice additions:
public static ProgressDialog createProgressDialog(Context context, String title, String message, boolean isCancelable)
{
ProgressDialog dialog = new ProgressDialog(context);
dialog.setTitle(title);
dialog.setMessage(message);
dialog.setCancelable(isCancelable);
return dialog;
}
If you are using AsyncTasks to do your work in the background, it is especially important to check that the Activity is still "alive" and not finishing when you show and dismiss the ProgressDialog, or your app will die with a bizarre exception(see this answer).
public static void safeShowProgressDialog(Context context, ProgressDialog dialog)
{
if(!((Activity) context).isFinishing())
{
dialog.show();
}
}
Same for dismissing the dialog:
public static void safeDismissProgressDialog(Context context, ProgressDialog dialog)
{
if(!((Activity) context).isFinishing())
{
dialog.dismiss();
}
}
See the API reference:
http://developer.android.com/reference/android/app/ProgressDialog.html
Here is good example:
Let's say you try to login and wait response from Server. On wait you show Progress Dialog and on Success switch login activity to Main:
private ProgressDialog dialog;
...
dialog = ProgressDialog.show(FirstLoginActivity.this, "", "Connecting. Please wait...", true);
HeavyTask task = new HeavyTask();
task.execute(str1, str2);
private class HeavyTask extends AsyncTask<String, Void, Void> {
private String str1= "";
private String str2= "";
protected Void doInBackground(String... args) {
str1= args[0];
str2= args[1];
try {
doSomething(str1, str2);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void results) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
doStuff(str1, str2);
}
}, 500);
}
private void doStuff(String str1, String str2) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent().setClass(FirstLoginActivity.this, OtherActivity.class).setData(getIntent().getData()));
Toast.makeText(getApplicationContext(), "Registration succeeded.", Toast.LENGTH_LONG).show();
//kill the dialog waiting
dialog.dismiss();
dialog = null;
}
}, 1000);
}
You can find some guidance in the Android Design documentation: http://developer.android.com/design/building-blocks/progress.html
you can use progress bar. i usually use it through asyctasks. and overload the following method as:
protected void onProgressUpdate(Integer... progress) {
((ProgressBar) findViewById(R.id.progressBar1)).setProgress(progress[0]);
}
Depending on your application design it would vary but a ProgressDialog is a fairly common solution. This tutorial would show you how it all get's tied together and the two variations (with or without displaying progress).
Dear Android hackers,
I am trying to do the following in my Android App: When the User clicks on a list item in a ListActivity, a ProgressDialog should show up, some preloading should happen and after it's done, another Activity should be called using an intent.
I tried different approaches. What didn't work at all was using an Async Task. Apparently I cannot show, dismiss or edit my ProgressDialog out of the Async Task, if that Class is not a Member of my original Activity.
I switched to a simple Thread then, this is how I'm trying to do it:
dialog = ProgressDialog.show(BookmarkActivity.this, "", "Loading...",true);
new Thread() {
public void run() {
// do something
dialog.setMessage("Change Message...");
// do more
dialog.dismiss();
// ...
Intent intent = new Intent(BookmarkActivity.this, ThreadActivity.class);
BookmarkActivity.this.startActivity(intent);
}
}.start();
This works almost, but the changing of the dialog message does not. I'm getting errors saying something about "leaked windows". (I can post the complete log if it is needed).
My questions:
How can I use an Async Task for this, where the Class has it's own file?
How can I change the ProgressDialog out of my Thread or AsyncTask without causing an error for changing the UI in another thread?
Thanks in advance, Jan Oliver
Ok, with the help of Jason, I put together this Async Task. That works!
public class ThreadPreLoader extends AsyncTask<Object, String, Void> {
private Activity mActivity;
private ProgressDialog mDialog;
public ThreadPreLoader(Activity activity) {
mActivity = activity;
}
protected void onPreExecute() {
mDialog = new ProgressDialog(mActivity);
mDialog.setMessage("Loading...");
mDialog.show();
}
protected Void doInBackground(Object... args) {
publishProgress("Loading something else..");
return null;
}
protected void onProgressUpdate(String... msg) {
mDialog.setMessage(msg[0]);
}
protected void onPostExecute(Void result) {
mDialog.dismiss();
}
}
Thanks again, Jason.
You should use an Async Task, Define a custom Async Task which receives the context (this) of the original activity.
Then keep that context for later Dismissing the dialog.
From your doInBackground() method you can call postProgress( int progress) which will cause onProgressUpdate() to be called in the async task , this method is on the UI thread so it will not cause cross thread errors.
Once doInBackground() is complete the method onComplete() will also be called on the UI thread, this is where you can use your saved context and dissmiss the dialog (context.dissmissDialog()
Take a look at Android's Handler class. If you create the Handler in the onCreate method of your activity, Runnables that are sent to the post method of the handler are then run on the UI thread of your activity:
Handler h;
protected void onCreate(Bundle bundle) {
h = new Handler;
new Thread() {
public void run() {
// your run code
h.post(new Runnable() { /* change dialog here */ });
}
}.start();
}
I'm not sure that's the best option, but worth a try.
In AsyncTask
You should do you work which need time in doInBackground and calling intent like things, that you need to do after this task should be in onPostExecute
public class ThreadPreLoader extends AsyncTask<Object, String, Void> {
private Activity mActivity;
private ProgressDialog mDialog;
public ThreadPreLoader(Activity activity) {
mActivity = activity;
}
protected void onPreExecute() {
mDialog = new ProgressDialog(mActivity);
mDialog.setMessage("Loading...");
mDialog.show();
}
protected Void doInBackground(Object... args) {
//do more
publishProgress("Loading something and reached somewhere..");
//do more
publishProgress("Loading something and reached somewhere..");
//do more
return null;
}
protected void onProgressUpdate(String msg) {
mDialog.setMessage(msg);
}
protected void onPostExecute() {
Intent intent = new Intent(BookmarkActivity.this, ThreadActivity.class);
BookmarkActivity.this.startActivity(intent);
mDialog.dismiss();
}
}