Unfortunately, using the progress dialog can be painful. Frustratingly, many tutorials show you how to instantiate a ProgressDialog but not how to use it properly, failing to mention that if you make a blocking call on the UI thread (like an HTTP request), the ProgressDialog will never actually appear. After 2 seconds, the Android OS will think your app has frozen and kill it. Great.
Many forum posts suggest using Android's AsyncTask to execute the "work" in the background (AsyncTask is supposed to be easier to use than creating a new thread), but I've found AsyncTask to be more headache than help. Just create a thread. It's not hard.
FYI, ProgressDialog requires a context (the calling activity), a message to display, and a handler to do some work. Your handler can only receive ONE variable, so I tend to use a HashMap so I can pass multiple bits of data.
I've come up with a pattern that I've reused and works well. Here we go!
- Create a thread class.
- Add a thread and a null handler to your activity.
- Create the ProgressDialog in your Activity's onCreate
- Create a handler.
- Instantiate your worker thread
- Implement onPause for your activity to stop the worker thread if the activity is paused(and possibly onResume-- though be aware that onResume will be called before onCreate)
public class WorkerThread extends Thread {
private ProgressDialog dialog;
private Handler handler;
private HashMap messageData = new HashMap();
// .. put your constructor etc here ...
public WorkerThread(ProgressDialog dialog, Handler handler) {
this.dialog = dialog;
this.handler = handler;
}
public void run() {
// Var to keep track of whether the work succeeded or not
Boolean status = true;
// ... do some work here ...
// If an error occurred...
if(error) {
status = false;
messageData.put("message", "Error message goes here");
}
messageData.put("status", status);
// Send a message back to calling activity
handler.obtainMessage(0x2a, messageData).sendToTarget();
// Dismiss dialog
if (dialog != null && dialog.isShowing())
dialog.dismiss();
}
// Clean up if the thread is cancelled
public void cancel() {
messageData.put("status", false);
handler.obtainMessage(0x2a, messageData).sendToTarget();
if (dialog != null && dialog.isShowing())
dialog.dismiss();
}
}
WorkerThread WorkerThreadInstance = null;
Handler handler = null;
ProgressDialog workDialog = ProgressDialog.show(this, "", "Working...", true);
// Handle response from the worker thread
handler = new Handler() {
@SuppressWarnings("unchecked")
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
HashMap data = (HashMap) msg.obj;
Boolean status = (Boolean) data.get("status");
if (status==true) {// if successful
Toast.makeText(getApplicationContext(), "Work was successful",
2000).show();
// Process return data here
// Uncomment the next line if your activity should end once processing is done
//finish();
} else {
if(data.get("message")!=null) {
Toast.makeText(getApplicationContext(), "Work failed!" + data.get("message") ,
3000).show();
}
// Uncomment the next line if your activity should end after an error
//finish();
}
}
};
// Create an instance of the worker thread
WorkerThreadInstance = new WorkerThread(workDialog, handler);
WorkerThreadInstance.start();
@Override
public void onPause() {
super.onPause();
if (WorkerThreadInstance != null) {
WorkerThreadInstance.cancel();
// Mark thread for deletion by GC or there will be a memory leak
WorkerThreadInstance = null;
}
}
1 comment:
C for Cat
C for Cat
C for Cat
C for Cat
C for Cat
C for Cat
Post a Comment