I use AsyncTask in my App for download a url. I use a ProgressDialog on onPreExecute() for waiting.
But I cant see ProgressDialog while process finish and i see it for a moment. want to see it while downloading not after that.
can any one help me.
thanks
my code is like this:
private class loadMoreListView extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
pDialog = new ProgressDialog(SingleMenuItemActivity.this);
pDialog.setMessage("Please Wait ...");
pDialog.isIndeterminate();
pDialog.setCancelable(false);
pDialog.show();
}
protected Void doInBackground(Void... unused) {
runOnUiThread(new Runnable() {
public void run() {
// do something for downloading
}
});
return (null);
}
protected void onPostExecute(Void unused) {
// closing progress dialog
pDialog.dismiss();
}
}
runOnUiThread(new Runnable() {
public void run() {
// do something for downloading
}
// do something for downloading, inside runOnUiThread, is wrong. runOnUiThread makes "do something for downloading" run on the UI Thread, and your application should crash for NetworkOnMainThreadException, you the app runs on a device with a version of android grater than GingerBread. Differently it will block the ui thread preventing him to draw your progress bar
The problem is in
runOnUiThread(new Runnable() {
public void run() {
// do something for downloading
}
});
ProgressDialog will not update if the UI thread is still busy. There are many examples in SO for that.
I don't understand why do you need UIthread.
And as a rule of thumb - if you need Progress dialog, you need to let run asynctask in background thread,as it always do.Read the document
http://developer.android.com/reference/android/os/AsyncTask.html
You can use the below example
http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
Firstly notice the "#override" header attached to all the AsyncTask Implemented methods e.g.
private class loadMoreListView extends AsyncTask<Void, Void, Void> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pDialog = new ProgressDialog(SingleMenuItemActivity.this);
pDialog.setMessage("Please Wait ...");
pDialog.isIndeterminate();
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pDialog.cancel();
}
}
Also Remove this from doInBackground unless you must do something on the UI.
runOnUiThread(new Runnable() {
public void run() {
// do something for downloading
}
});
You cannot do something for downloading on the runOnUiThread. doInBackground is meant for running background tasks like downloads etc. not visible to the UI.
Related
I am developing an Android app which has 2 classes. Game, which extends Activity, and GameView, which extends View.
When the game is loaded, it sets the content view to GameView, which is just a drawing class that uses a canvas to display the game.
I am trying to create a ProgressDialog in the Game class which will show a spinner after a certain action has been done, as this takes a long time to complete. So far I have the following:
setContentView(R.layout.activity_game);
ProgressDialog pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Calculating hint");
pd.show();
AsyncTask<String[][], Void, SudokuSquare> nextSquareThread = new GetNextSquare().execute(puzzleNumbers);
next = nextSquareThread.get();
pd.dismiss();
setContentView(gameView);
And my AsyncTask class looks like this:
private class GetNextSquare extends AsyncTask<String[][], Void, SudokuSquare> {
private ProgressDialog dialog = new ProgressDialog(Game.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Finding next number");
this.dialog.show();
}
#Override
protected SudokuSquare doInBackground(final String[][]... args) {
try {
SudokuAdvancedSolver solver = new SudokuSolver(args[0]);
return solver.getOneValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Override
protected void onPostExecute(final SudokuSquare result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
At the moment I have two ProgressDialogs, one inside the AsyncTask and one outside. Which one is correct? Also, the spinner is not being displayed at all. What am I overlooking which is causing this to be the case?
only the one outside is correct. because you are trying the main thread (the UI thread of your activity) by another thread (your asychronic task). you should use a handler in place of this :
1/ you show the progress bar
2/ you load the game in a thread
3/ when the game is loaded you send a message to the handler which will stop the progress bar.
See this exemple . you should dismiss your dialog in the handler (when the handler receives the message from the thread) .
If you don't implement a listener on Asynctask, i could suggest you to dismiss your progress dialog onPostExecute
private ProgressDialog dialog;
public void setProgressDialog(ProgressDialog dialog){
this.dialog = dialog;
}
#Override
protected void onPostExecute(final SudokuSquare result) {
dialog.dismiss();
}
and before you executing Asynctask add this code
nextSquareThread.setProgressDialog(pd);
I am quite new to Android/Java, and my first app is using MetaIO SDK.
I am trying to implement "Loading" progress bar, while app (MetaIO SDK) is loading.
Overlay background is shown
Loading dialog is appeared and "loading image" starts spinning
Overlay background disappears and loading image stops spinning <- the problem
After 2-3 seconds it unfreezes and ARELViewActivity is executed.
The code:
public void onScanButtonClick(View v)
{
new ScanLoadingDialog().execute(0);
}
private class ScanLoadingDialog extends AsyncTask<Integer, Integer, Boolean>
{
//Before running code in separate thread
#Override
protected void onPreExecute()
{
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(false);
progressDialog.show();
}
#Override
protected Boolean doInBackground(Integer... params)
{
try
{
synchronized (this) {
AssetsManager.extractAllAssets(getApplicationContext(), true);
startActivity( new Intent(getApplicationContext(), ARELViewActivity.class));
}
}
catch (IOException e)
{
MetaioDebug.log(Log.ERROR, "Error extracting assets: "+e.getMessage());
MetaioDebug.printStackTrace(Log.ERROR, e);
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result)
{
progressDialog.dismiss();
finish();
}
}
Am I doing something wrong?
P.S. Full source code can be found here: link text
P.S.S. Related to this question, but I am using technique suggested there, and it still doesn't want to work
I had a similar problem and i solved it by running the UI handling code on the UI thread like so
runOnUiThread(new Runnable() {
#Override
public void run() {
if (imgvExampleOverlay != null)
imgvExampleOverlay.setVisibility(View.VISIBLE);
}
});
imgvExampleOverlay is an image like the one the user has to capture.
Hope this helps
private class Test extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
Log.d("test", "called1");
}
#Override
protected Void doInBackground(Void... params) {
Log.d("test", "called2");
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.d("test", "called3");
}
}
and output:
test:called1
Why other methods never don't called when Service work on background? If service stop, then all method calls and output:
test:called1
test:called2
test:called3
I guess you are testing on android 3.x or newer and you are simply affected by the change made to the way AsyncTask is executed.
This is how I handle this in my code to always work the same fully parallel:
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new Test().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new Test().execute();
}
Basically change in AsyncTask appeared in Honeycomb (see Android SDK docs here in "Order of execution" section), so before that, you launch it as usual, for HC and up, use executeOnExecutor() if you do not like new behaviour (noone does, I think)
How do i make sure that the async tasks finishes before i run certain tasks. I need to use a variable AFTER the async tasks changes the value of that variable. If i run the code before async is done running then im screwed. any help? im obviously new to async tasks. If you look at my code im probably not using onPostExecute() as it was intended so advice would be helpful. My initial thought was to keep adding things to the async task but im thinking that this is just bad practice since i have tons of things that must be run in series. Basically, what i think it boils down to is: how do i make sure that the tasks in the UI thread dont start to run before my async task has finished.
public class MainActivity extends MapActivity {
myJSONmap;
public void onCreate(Bundle savedInstanceState) {
new AsyncStuff().execute();
locatePlace(myJSONmap);
class AsyncStuff extends AsyncTask<Void, Integer, JSONObject> {
#Override
protected JSONObject doInBackground(Void... params) {
jObject = GooglePlacesStuff.getTheJSON(formatedURL);
return null;
}
#Override
protected void onPostExecute(JSONObject result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
myJSONmap = JSONextractor.getJSONHMArrayL(jObject); // getting the parsed data from the JSON object.
//the arraylist contains a hashmap of all the relevant data from the google website.
}
}
You probably want to read more about AsyncTask on Android Developer
http://developer.android.com/intl/es/reference/android/os/AsyncTask.html
About tips, my personal choice is to pass a Boolean to onPostExecute. That way you can evaluate if the doInBackground was succesful, an then figure out what to do (Error message or update the layout).
Keep in mind that in onPostExecute method ideally should only make the screen update, assuming you have the data ok. In your example, why not include the
myJSONmap = JSONextractor.getJSONHMArrayL(jObject);
on the doInBackground? And then call
locatePlace(myJSONmap);
Like this:
class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
String errorMsg;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Integer doInBackground(Void... v) {
try{
jObject = GooglePlacesStuff.getTheJSON(formatedURL);
myJSONmap = JSONextractor.getJSONHMArrayL(jObject);
//do stuff
return true;
} catch (JSONException e){
errorMsg="Something wrong in the json";
return false;
}
}
#Override
protected void onPostExecute(Boolean success) {
if(success){
locatePlace(myJSONmap);
//update layout
} else {
//show error
}
}
}
You can ue below code to execute async task -
MyAsyncTask_a asyncTask_a = new MyAsyncTask_a();
asyncTask_a.execute();
Once doInBackground() task is finished then only control will go to postExecute().
You can't perform any UI operations in doInBackground , but you can do so in preExecute() and postExecute().
class MyAsyncTask_a extends AsyncTask<Void, Void, Integer> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Integer doInBackground(Void... arg0) {
// TODO Auto-generated method stub
return 1;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
Hope this will help you.
My application has a ViewFlipper with 3 ViewGroups in it. Each ViewGroup interaction is dependent on data from a database. I'm using an AsyncTask to read from a database and return a Cursor when it's done. Before the AsyncTask is executed, I just want to display a single View in the ViewFlipper saying "Loading data, please wait.", is this possible somehow?
Show the progress dialog in your onPreExecute() and dismiss it in the onPostExecute(). Something like this,
private class MyAsyncTask extends AsyncTask<Integer, Integer, Integer[]> {
private ProgressDialog myWait = null;
// This is on the UI thread itself
protected void onPreExecute() {
myWait = new ProgressDialog(MainActivity.this);
myWait.setMessage("Loading data, please wait");
myWait.setCancelable(false);
myWait.show();
}
// Separate worker thread is used here
protected Integer[] doInBackground(Integer...params) {
//do the database loading
return <your result - goes to onPostExecute>;
}
// This is on the UI thread itself
protected void onPostExecute(Integer[] resultCell) {
if (myWait != null) {
myWait.dismiss();
}
}
}
yes you can make use of progressDialog. Do it like this,
progressDiaolg=ProgressDialog.show(Activity.this,"","Loading Images...");
final Thread t= new Thread(new Runnable() {
public void run() {
Log.i("Inside Thread", "Downloading Images...");
downloadImages();
handler.sendEmptyMessage(0);
}
});
t.start();
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
try {
progressDiaolg.dismiss();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
};
I don't have idea with Asynctask. So try modifying this snippet accordingly.