please see my code .. and if you can, tell me why my progressDialog stopped when the function is halfway done in the background, the screen hangs (nothing is displayed, the logcat shows all logs i put in the background function).
Then, right before the end, the progressDialog starts animating again and closes after a couple seconds (the function is finished and the result is displayed normally)
public class changeWall extends AsyncTask<Integer, Integer, Integer> {
protected Integer doInBackground(Integer... urls) {
int totalSize=0;
try {
if(s.loadBoolean() == false)
{
log("IF = false");
log("tempLogin = "+tempLogin);
log("tempPassword = "+tempPassword);
getNewResponse(tempLogin,tempPassword);
if(needSave)
{
s.saveBoolean(true);
}
}
else
{
if(s.loadLogin()==null)
{
getNewResponse(tempLogin,tempPassword);
}else
{
getNewResponse(s.loadLogin(),s.loadPassowrd());
}
}
parser.setLol(0);
parser.startParse(RESULT_STRING);
log("end parse");
} catch (ClientProtocolException e) {
log("internet connection lost");
} catch (IOException e) {
// TODO Auto-generated catch block
log(" connection lost");
}
log("count = "+parser.getFacebookId(1));
publishProgress();
totalSize=1;
log("end of start");
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
log("wall click ON PROGRESS UPDATE");
wall.setBackgroundResource(R.drawable.tabbuttonon);
messages.setBackgroundResource(0);
activity.setBackgroundResource(0);
profile.setBackgroundResource(0);
l1_1.setBackgroundResource(R.drawable.tabbuttononleft);
l1_2.setBackgroundResource(R.drawable.tabbuttononright);
l2_1.setBackgroundResource(0);
l2_2.setBackgroundResource(0);
l3_1.setBackgroundResource(0);
l3_2.setBackgroundResource(0);
l4_2.setBackgroundResource(0);
l4_2.setBackgroundResource(0);
wall.setTextColor(Color.BLACK);
messages.setTextColor(Color.WHITE);
profile.setTextColor(Color.WHITE);
activity.setTextColor(Color.WHITE);
try {
loadWall();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
wallProgres.dismiss();
}
protected void onPostExecute(Long result) {
if(result==1)
{
log("end WallChange");
}
}
}
simple map as this showed :
----start progress(progress.show())
----start function
--- animation (progressDialog)
---animation(---)
---animation(---)
---FREEZ
---FREEZ(Function steel working normal, progressDialog in freeze mode)
---animation
---end function
---progress.dismis();//
similar problem i found here..(this problem = my problem but without download) Freezing UI Thread with AsyncTask
Regards,Peter.
It may not be correct but place
wallProgres.dismiss();
in onPostExecute rather than in onProgessUpdate method.
beacuse onProgressUpdate calls while running , but onPostExecute calls after execution.
Hope it helps..
place this line "wallProgres.dismiss()" in onPostExecute().
protected void onPostExecute(Long result) {
if(result==1)
{
log("end WallChange");
}
if(wallProgress.isShowing())
wallProgres.dismiss();
}
put this line
wallProgres.dismiss();
in onPostExecute() method
protected void onPostExecute(Long result) {
if(result==1)
{
log("end WallChange");
wallProgres.dismiss();
}
}
Related
I'm having trouble with AsyncTask running multiple methods in doInBackground. this is my AsyncTask code:
public class FETCHDATA extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
pdialog = new ProgressDialog(getContext());
pdialog.setTitle("Please Wait");
pdialog.setMessage("Fetching data...");
pdialog.show();
}
#Override
protected Void doInBackground(Void... voids) {
try{
method1();
method2();
method3();
method4();
method5();
method6();
method7();
}catch (Throwable e){
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Void aVoid) {
if (pdialog.isShowing()){
pdialog.dismiss();
}
}
Instead running and waiting the first method is done, the doInBackground proceeds to the next method. and the ProgressDialog dismiss by one second.
Note
Every Method will get data from our API and save it on my SQLiteDatabase .
QUESTION
How can i execute my methods when the first method has finished getting and saving data before moving to the second methods.
Maybe you have to create multiples AsyncTask and whenever the first method finish, communicate it with returning a boolean instead of void instance here ---> extends AsyncTask.
This is weird.
I assume that your methodX() are asynchronous call?
In that case, you can use Thread.join() or CountDownLatch.
You are violating usage of async task. Async task is designed for doing short async operations and update the UI easily before, during and after, It is not for doing 7 network & Sqlite operations at once.
You can read more here, : https://developer.android.com/reference/android/os/AsyncTask
So you need to implement some kind of job for yourself to execute these operations at once or use some popular libraries like Retrofit.
If you insist to use async task, since an async task need to be executed from UI thread, you need to create new async task an execute it from onPostExecute every time when it is done and you of course need to pass a param(a counter or something) to doInBackground to know which method should be called.
You can put a counter with a switch case statment in the doInBackground in wich you choose the methode to execute and then in the onPostExecute call new FETCHDATA().execute() recursively
EDIT : working code ( i forgot break; after case;)
int counter = 1; // global
class Fetchdata extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... voids) {
try {
switch (counter) {
case 1:
method1();
break;
case 2:
method2();
break;
case 3:
method3();
break;
case 4:
method4();
break;
case 5:
method5();
break;
default:
cancel(true);
counter = 1;
break;
}
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
counter+=1;
Log.d(TAG, "onPostExecute: "+counter);
// cancel(true);
new Fetchdata().execute();
}
}
void method1(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode1: coucou");
}
void method2(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode2: ");
}
void method3(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode3: ");
}
void method4(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode4: ");
}
void method5(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode5: ");
}
I think the problem is that your all methods or some methods already runs on a separate thread . So whenever you call a method which already runs on separate thread doInBackground() i.e current thread will not wait for it and continue the execution.
Apart from that The way you put try-catch is not a proper way to do it . Also if you want to call several threads one after another you should go with ThreadPoolExecuter.
If you are not using a Network library To make API calls you can use RetroFit.
I am trying to add some sleep-time in my Asynctask because right now my ProgressDialog is too fast when there isn't much data to load.
I tried this:
#Override
protected Boolean doInBackground(Void... params) {
try {
progressDialog.setMessage("Loading first thing...");
firstThing();
progressDialog.incrementProgressBy(1);
Thread.sleep(500);
//...repeat above four lines a few times for second, third, fourth thing, etc
return true;
}
catch (Exception e) {
Log.e("MyClassName", "There was an error: " + e);
return false;
}
}
I am getting the error "Only the original thread that created a view can touch its views."
You'll have to override onProgressUpdate() as well as doInBackground().
// do this before asynctask.execute();
progressDialog.setMessage("Loading first thing...");
#Override
protected Boolean doInBackground(Void... params) {
try {
firstThing();
Thread.sleep(500);
// this method invokes onProgressUpdate on the UI thread
publishProgress();
return true;
}
catch (Exception e) {
Log.e("MyClassName", "There was an error: " + e);
return false;
}
}
#Override
protected void onProgressUpdate(Void... params) {
progressDialog.incrementProgressBy(1);
}
I have to display different messages in progress dialog, when running in async task.
First I need to the display the message "Please wait", then "Downloading from server", then "Please wait for sometime".
I have tried with publishProgress but when I run the application, on my ProgressDialog, only the last message "Please wait for sometime" is displayed. How can I display the three messages?
private class Sample extends AsyncTask<String, String, String> {
ProgressDialog testdialog;
#Override
protected void onPreExecute() {
testdialog = new ProgressDialog(test.this);
testdialog.setTitle("Title");
testdialog.setMessage("Please wait ");
testdialog.setIndeterminate(false);
testdialog.setCancelable(false);
testdialog.setCanceledOnTouchOutside(false);
testdialog.show();
}
#Override
protected String doInBackground(String... urls) {
publishProgress("Downloading from server");
publishProgress("Please wait for sometime");
/* here I code the background downloading process*/
}
#Override
protected void onProgressUpdate(String... pro) {
testdialog.setMessage(pro[0]);
testdialog.setMessage(pro[1]);
}
#Override
protected void onPostExecute(String result) {
testdialog.dismiss();
}
}
try this code in doInBackground() it should display all messages with 2 seconds delay for each
except last one will remain on the dialog until dialog is dismissed or hidden
#Override
protected String doInBackground(String... urls) {
try {//this should let "Please wait " appears for 2 secs
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress("Downloading from server");
try {////this should let "Downloading from server" appears for 2 secs
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress("Please wait for sometime");
try {////this should let "Please wait for sometime" appears for 2 secs
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/* here i code the background downloading process*/
}
also for onProgressUpdate() the method is prepared to receive multi params, but you are sending only one, so no need to use pro[1], remove second setMessage() call
#Override
protected void onProgressUpdate(String... pro) {
testdialog.setMessage(pro[0]);
}
I have 2 Asynctask, 1 for get data (location) from server then set a marker on map with this location and another call 1st Asyntask in a loop for updating location.
Here my code:
public class AsynComp extends AsyncTask<Void, Void, Void> {
ProgressDialog taxiDialog;
#Override
protected Void doInBackground(Void... params) {
jsonComp = new JSONComp(find_url);
find_status = jsonComp.getJsonStatus(txt_search);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (find_status.equals("2013")) {
Toast.makeText(getBaseContext(), "no result",
Toast.LENGTH_SHORT).show();
} else if (find_status.equals("2012")) {
for (Marker marker:markers){
if(marker.getTitle().equals(compFollow)){
marker.remove();
}
}
for (int i=0; i<number;i++){
comp = new Comp(jsonComp.getJsondata(i));
SetMarkerComp(comp);
try {
Thread.sleep(1400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class AsynFollow extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
if (!taxiFollow.equals("")) {
number = 1;
txt_search = compFollow;
find_url = "http://192.111.125.80:8001/Default.aspx?username="
+ Id + "&password=" + Pass + "&sohieuxe="+txt_search;
while (!stop){
new AsynComp().execute();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
taxiFollow = "";
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (!compFollow.equals("")) {
Toast.makeText(getBaseContext(), "Follow "+compFollow, Toast.LENGTH_SHORT).show();
} else {
iv_theodoi.setVisibility(View.VISIBLE);
iv_theodoif.setVisibility(View.GONE);
Toast.makeText(getBaseContext(), "Plz choose a marker", Toast.LENGTH_SHORT).show();
}
}
}
And i have 2 buuton, 1 to call AsynFollow.execute(), another to stop it.
This code can run but app will force close after awhile.
Any solution? thanks.
P/s: i'm a newbie in android.
You shoulnd you asyncTask for this. For repetitive action, like changing status in some interval, use Timer class. In this way you can implement repetitive action which can be repeated in intervals.
In this way you can stop this time by on click listener. You can run two times and specify it's realtions using other variables.
If you're newbe, you should read about multitasking in Android: Timer, AsyncTask, Handler.
In my opinion this docs will tell you much more than thousands of comments in stackoverflow.
In the first run of my app, i have to copy database file to data folder. it takes about 10 sec and in this period of time user sees a black screen. I want to use AsynTask technique to show a progressbar. but it doesnt work an i see that progressbar after black screen goes away...
with this code i call copy database class and also i call AsynTsk process...
new asyn().execute();
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
// throw new Error("Unable to create database");
}
and this is my AsynTask code:
public class asyn extends AsyncTask<String, Integer, String> {
ProgressDialog dialog;
#Override
protected void onPreExecute()
{
//loading toast
//final DataBaseHelper myDbHelper = new DataBaseHelper(this);
String firstload2 = myDbHelper.getfirstload();
if(firstload2.matches("1")) {
dialog=new ProgressDialog(DictionaryActivity.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMax(100);
dialog.show();
myDbHelper.changefirstload();
}
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
// perform desired task in this doInBackground Block.
for(int i=0;i<20;i++)
{
publishProgress(5);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return "";
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
dialog.incrementProgressBy(5);
}
#Override
protected void onPostExecute(String result)
{
dialog.dismiss();
AlertDialog.Builder a=new Builder(DictionaryActivity.this);
a.setMessage("Successfully Done");
a.setTitle("Try");
a.setPositiveButton("OK",null);
a.show();
}
}
where is my fault? how i can fix that?
myDbHelper.changefirstload(); should be within the doInBackground() method. onPreExecute() executes on the UI thread.
In terms of a progress bar, that's a bit difficult here. Personally, I'd do an indeterminate progress bar (just a spinning icon or something while it loads). If you want to have a % bar, though, you will need to break up the method into multiple methods, then update your progress in between them.