I have a splash screen which check an URL if there's any new content on the server. If show i wish to show a AlertDialog, to the app user so that depending on the action of user,i.e if YES download new contents from the server and get it to database else if NO load the contents for the app from the server.
However i am not being able to use an alert dialog inside AsyncTask
My snippet code is as:
protected String doInBackground(String... mode){
/* I AM QUERY MY DATABASE FOR THE PREVIOUS CONTENT(SAY CONTENT 1, CONTENT 2);
* then i start my connection to the server which has an xml file with the content
* info (say content 3), at this stage .
* i Check certain condition here,
* say if result ==0 then i wish to display an alertdialog.
* I used an alert dialog and i get some error. Stating use Looper or Handler.
* Can anyone help me with this?
*/
}
Edited
So in
doInBackGround(String... mode){
if(result==0){
// how do i implement this alert show that if the dialog appears and on clicking Yes i wish to exectute the URL handling part below
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Updates Found");
alert.setMessage( "New Updates for has been found.\n Would you like to download ?\n"
+ "Whats the update: Checking "+pld.result.get(i).get( "issue" ));
alert.setIcon(android.R.drawable.ic_dialog_info);
alert.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
try {
URL url = new URL(pld.result.get(i).get("link"));
ManageZipFile.getArchive(url,pld.result.get(i).get("issue"), file);
}
catch (Exception ex) {
Log.d(TAG, "Exception from URL"+ ex.getMessage());
}
progressState += updateProgressBar(20);
pld.saveCoverData(pld.result.get(i).get("issue"));
try {
pldContent = new PullLoadData(getString(R.string.files_path)
+ pld.result.get(i).get("issue")
+ "/contents.xml",context);
pldContent.getNewsItems();
progressState += updateProgressBar(20);
}
catch(XmlPullParserException e) {
Log.e(TAG, "GetNEWSITEM "+ e.getMessage());
}
catch (IOException e) {
Log.e(TAG, "XML FIle not found" + e.getMessage());
}
}
});
alert.setNegativeButton(android.R.string.no,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int arg1) {
dialog.dismiss();
}
});
AlertDialog showAlert = alert.create();
showAlert.show();
}
}
This is because the method doInBackground runs on a non-UI thread, and an AlertDialog needs to be displayed on the UI-thread.
To solve your problem, move the code for your AlertDialog to the method onProgressUpdate in AsyncTask, then when you want to display the Dialog call publishProgress() from doInBackground
protected String doInBackground( String... mode ) {
if( something )
//Conditions for showing a Dialog has been met
}
protected void onProgressUpdate( Void... params ) {
//Show your dialog.
}
If you need to pass some kind of variable/data to the dialog, you can pass the kind of data you declared in extends AsyncTask<Params, Progress, Result> - where Progress is the type of parameter you can pass via the publishProgress( myVariable )-method.
UI thread means it is associated directly with your UI.you cant do operations like network datafetch,disk access etc which require large processing time in your UI thread. They should be done in seperate thread.
AsyncTask helps to carry out theese operations in seperate thread which may otherwise results in infamous ANR error.(application not responding).
AsyncTask contain methods like onPreExecute() onPostExecute() onProgressUpdate() ,doInBackground ()etc you can access UI thread from onPreExecute() onPostExecute() onProgressUpdate() .The operation requiring longer processing time should be carried out in doinbackground().
I can't understand the functionality demands from your question but if you want to display Alert Dialog before data fetching operation,Display it from onPreExecute()
or if you want to display after data fetch Do it from onPostExecute().
Related
I have this code and it goes to catch as soon as it hits Source.httpConn and it sends the exception down below to catch.
try
{
JSONTokener sbTokener = new JSONTokener(Source.httpConn(infoUrlStr, Main.this).toString());
//array için hazırlandı
JSONArray jArray=new JSONArray(sbTokener);
//arraye eklendi
for(int i=0; i<(jArray.length()); i++)
.
.
.
}
Down in the catch part there is my alert dialog method. It normally works pretty well but I suspect that I have the problem because of the doInBackground. The application crashes before displaying the below alert dialog. All the try-catch is in my doInBackground method in ASyncTask.
catch (Exception e) {
AlertDialogDisp(Main.this, noServ, noServLog);
}
How can I make my application NOT crash and just display this alert dialog and then return to my Main activity as it was. Here is my alert dialog method:
protected void AlertDialogDisp(Context dialogContext, String head, String log) {
new AlertDialog.Builder(dialogContext)
.setTitle(head)
.setMessage(log)
.setPositiveButton("okay", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// On Alert Dialog Button
dialog.dismiss();
}
})
.show();
}
You cannot update ui from doInbackground. doInbackground is invoked on a backgroudn thread. Ui should be updated on the ui thread. Return result in doInbackground and update ui in onPostExecute
For more info check the docs
http://developer.android.com/reference/android/os/AsyncTask.html
You can also use runOnUithread which is a method of activity class
runOnUiThread(new Runnable(){
public void run() {
// dispaly dialog here
// no network related operation here
}
});
Show your dialog in runOnUiThead which is a method of activity class.
runOnUiThread(new Runnable(){
public void run() {
//write your alert dialog code here
}
});
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...)
In my app i m trying to fetch data from server and storing in database.
When it is doing all these work i want at that time progressdialog should show, if successfully data fetches then dialog should close and some alertDialog should show for msg "successfully data fetched". and if any n/w problem there, then it should show different msg that "problem with n/w".
for that i am doing like below,
public void onClick(View arg0) {
myProgressDialog = ProgressDialog.show(
getParent(), "Please wait...",
"Doing upgrade...", true);
new Thread() {
public void run() {
try {
upgradeAll();//function where data fetched from server
sleep(5000);
} catch (Exception e) {
}
// Dismiss the Dialog
myProgressDialog.dismiss();
Toast.makeText(UpgradeAllTableData.this, "Due to some internal problem \n" +
"it couldnot update..", Toast.LENGTH_LONG).show();
}
}.start();
}
AsyncTask code,
private class UpgradeTask extends AsyncTask<Context, Void, Void> {
private ProgressDialog Dialog = new ProgressDialog(UpgradeAllTableData.this);
#Override
protected void onPreExecute() {
System.out.println("In onPreExecute ");
Dialog.setTitle("Loading");
Dialog.setMessage("Please wait for few seconds...");
Dialog.show();
}
#Override
protected Void doInBackground(Context... params) {
System.out.println("In doInBackground ");
upgradeAll();
System.out.println("In doInBackground after fetching");
return null;
}
#Override
protected void onPostExecute(Void unused) {
System.out.println("In onPostExecute ");
Dialog.dismiss();
Toast.makeText(UpgradeAllTableData.this, "Problem with internet" , Toast.LENGTH_SHORT).show();
alertboxNeutral("Warning", "Problem with Internet Connection", "Okay","Try again");
}
}
Problem is Toast is not showing. why?
My question is which condition and where to give so that if any problem with n/w then it show some msg and success then show another msg.
Where i should write code for that?
Give me some suggestion.
Thank you
Not exactly an answer to your particular question, but have you considered AsyncTask? It's pretty much designed to handle situations like yours, where a task is performed async while showing some progress (and eventual result) on the UI thread. Alternativelly, you could broadcast an intent and have your activity catch it to show the toast, since your Toast should be show from your UI thread as well.
update:
AsyncTask reference - http://developer.android.com/reference/android/os/AsyncTask.html
What you are doing is totally wrong. UI thread handles all UI changes, but here you are creating ProgressDialog in UI thread and dismissing it in some Other Thread.. A solution is make use of AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html
Tips or ideas on how ProgressDialog can communicate with asyncTask.
For example when I click the button, the program will validate the input to internet, This is should not be interupted. so I use ProgressDialog.
After progressDialog.dismiss(), I need to refresh the view by calling the asyncTask.
I have tried some ways but it's failed, for example
* I execute asynTask after progressdialog.dismiss().
* put execution asynctask inside dialogbox after progressdialog thread.
in other word, is there any way to tell asynctask that progressdialog has been dismissed. Or is there communication such as message between threads ?
here is the example of my code:
btnPost.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stockProgressDialog = ProgressDialog.show(PostActivity.this,
"Please wait...", "Check the post");
new Thread() {
public void run() {
try{
/* Connect to Internet API */
stockProgressDialog.dismiss();
} catch (Exception e) { }
// Dismiss the Dialog
}
}.start();
new LookUpTask().execute();
}
});
Yes, there is a way to tell asyncTask that progressDialog has been dismissed. you can use one onDismissListener
#Override
public Dialog onCreateDialog(int id){
if(id==DIALOG_PROGRESS_DIALOG){
stockProgressDialog = new ProgressDialog(Main.this);
stockProgressDialog.setTitle("Please wait...");
stockProgressDialog.setMessage("Check the post");
stockProgressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
textView.setText("Waiting the 5 secs...");
myAsyncTask.execute("start it");
//Or myAsyncTask.cancel(true); if you want to interrupt your asyncTask
}
});
return stockProgressDialog;
} else return super.onCreateDialog(id);
}
You can cancel an AsyncTask by calling AsyncTask.cancel(..) and then start up a new AsyncTask. You are not supposed to run the AsyncTask as a parallel activity - it is supposed to be able to run and finish without outside intervention.
Extend async and look into returning a result from doInBackground. onProgress update can dismiss your Progress dialog under control of the async task. Handle the result from doInBackground in onPostExecute.
//create the task
theBackground = new Background();
theBackground.execute("");
--------
private class Background extends AsyncTask<String, String, String>{
protected String doInBackground(String...str ) {
publishProgress("##0");
//do a bunch of stuff
publishProgress(#001);
return("true");
}
protected void onProgressUpdate(String... str ) {
//do stuff based on the progress string and eventually
myProgressDialog.dismiss();
}
protected void onPostExecute(String result) {
}
}
I'm not sure why you're using a thread in one case, but an AsyncTask in another when you could just use two AsyncTasks... Actually, unless I'm missing something, in your case the most straightforward way is to combine the two bits of work into one AsyncTask and simply create and destroy the dialog in the AsyncTask callbacks. In pseudo-code:
onPreExecute
show dialog
doInBackground
do internet stuff
onPostExecute
update views
close dialog
Is there a reason why you're trying to update the views in its own AsyncTask? If you're updating views, you probably need to do the work in the UI thread anyway...
I'm using following code to fill a custom ListPreference dialog. Since the fill procedure takes a lot of time i want to show a progress dialog during the fill procedure.
My problem is that filler.execute() does not block onPrepareDialogBuilder and functions goes till the end before values are filled causing an exception... Any idea?
#Override
protected void onPrepareDialogBuilder(Builder builder) {
// Load data
if (this.getEntries()==null) {
FillerTask filler = new FillerTask();
filler.execute();
}
Log.d(TAG, "Filler finished");
super.onPrepareDialogBuilder(builder);
}
Here is Filltertask code, basically he looks for every activity with a MAIN Intent filling a list:
private class FillerTask extends AsyncTask<Void, Void, String[][]> {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
Log.d(TAG, "Dismiss dialog");
dialog = ProgressDialog.show(MyListPreference.this.getContext(), "", "Doing stuff...", true);
}
#Override
protected String[][] doInBackground(Void... params) {
return fill();
}
public String[][] fill() {
Log.d(TAG, "Fill started");
CREATE LISTS...
// Done
Log.d(TAG, "Fill done");
String[][] result = new String[][] {entryNames, entryValues};
return result;
}
#Override
protected void onPostExecute(String[][] result) {
Log.d(TAG, "Post execute");
MyListPreference.this.setEntries(result[0]);
MyListPreference.this.setEntryValues(result[1]);
dialog.dismiss();
}
}
My problem is that filler.execute() does not block onPrepareDialogBuilder and functions goes till the end before values are filled causing an exception... Any idea?
That is the entire point behind an AsyncTask. The "Async" in AsyncTask means asynchronous.
Use your AsyncTask to get your data. Then, in onPostExecute(), display the dialog.
Found the solution, best way to do this is override the onClick method and let the AsyncTask postExecute call the "super()", so click is not passed until content is loaded and during load progress bar is correctly displayed.
asyntask doesn't lock main thread, it just drops a message to message queue of main thread