I'm receiving json data from an api using Retrofit, and works perfectly, but in the future I want to show a progress bar. I decided to implement the onProgressUpdate in order to check if this method is invoked, but when checking the Logcat tab, it's not working. That is, the method is not running. All other methods inside the AsyncTask class are working. I have a Toast for each method and all of these run.
public class MindicadorTask extends AsyncTask<Void, Void, Void> {
private String TAG = MindicadorTask.class.getSimpleName();
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(MainActivity.this, "JSON Downloading", Toast.LENGTH_SHORT).show();
}
#Override
protected Void doInBackground(Void... voids) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(IMindicador.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
IMindicador iMindicador = retrofit.create(IMindicador.class);
Call<Mindicador> call = iMindicador.getAPI();
mMindicador = new Mindicador();
try {
mMindicador = call.execute().body();
} catch (IOException e) {
Log.e(TAG, "" + e.getMessage());
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
Log.e(TAG, "onProgressUpdate was called");
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(MainActivity.this, "JSON Call was sucessfull", Toast.LENGTH_SHORT).show();
}
}
You have to pass it some value, instead of Void. Try using an int, for example. As the int iterates, it calls onProgressUpdate().
Specify the type data which you want to send to onProgressUpdate method.also call publishProgress method inside doInBackground method which trigers onProgressUpdate method call.
Related
I have this GetAllUsers(); in onCreate and I have this
private void GetAllUsers() {
(new LoadingUsers(this)).execute();
}
Then I have this
private class LoadingUsers extends AsyncTask < Void, Integer, String > {
String TAG = getClass().getSimpleName();
AlertDialog.Builder builderSingle;
ArrayAdapter < String > arrayAdapter;#
SuppressWarnings("unused")
Context mContext;
public LoadingUsers(Context context) {
super();
mContext = context;
}
protected void onPreExecute() {
// prgDialog.show();
// builderSingle = new
Log.d(TAG + " PreExceute", "On pre Exceute......");
}
protected String doInBackground(Void...arg0) {
Log.d(TAG + " DoINBackGround", "On doInBackground...");
return null;
}
protected void onProgressUpdate(Integer...a) {
super.onProgressUpdate(a);
Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
}
protected void onPostExecute(String result) {
// prgDialog.hide();
Log.d(TAG + " onPostExecute", "" + result);
MainActivity.this.pd.dismiss();
}
}
I wanted to put a builderSingle = new AlertDialog.Builder(MainActivity.this); inside the protected void onProgressUpdate(Integer... a) { which has a AsyncHttpClient client = new AsyncHttpClient(); but unfortunately the onProgressUpdate does not get called at all. I know this because the log does not show. All other log are showing except the onProgressUpdate I have also have
#
Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "On Destroy .....");
}
#
Override
protected void onPause() {
super.onPause();
Log.i(TAG, "On Pause .....");
}
#
Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "On Restart .....");
}
#
Override
protected void onResume() {
super.onResume();
Log.i(TAG, "On Resume .....");
}
#
Override
protected void onStart() {
super.onStart();
Log.i(TAG, "On Start .....");
}
#
Override
protected void onStop() {
super.onStop();
Log.i(TAG, "On Stop .....");
}
OnStart and OnResume are being log as well.
Why is onProgressUpdate not being called?
How to call the onProgressUpdated correctly?
Update
onPostExecute is being called as well on the onProgressUpdate is not
onProgressUpdate is called on the main thread each time publishProgress is called from within doInBackground (on the background thread). This facility is provided for your convenience if you choose to use it. It's primarily useful if your task involves some kind of loop, in which case you can call publishProgress at each iteration. If your task simply invokes some other code, and all the processing happens somewhere you can't control, then the publishProgress/onProgressUpdate mechanism isn't going to be useful to you. In that case, you might decide to display an indeterminate progress bar before starting the task and then hide the indeterminate progress bar after it's completed.
It should be very simple
private class LoadingUsers extends AsyncTask< Void, Integer, String > {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = ProgressDialog.show(getContext(), null, "Loading users...", false);
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
dialog.setProgress(values[0]);
}
#Override
protected String doInBackground(Void... params) {
// Doing something in loop
int max = 1024;
for (int i = 0; i < max; i++) {
int percentageCompleted = i*100/max;
publishProgress(percentageCompleted);
}
return "";
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
dialog.dismiss();
}
}
Let me know if you didn't understand what is this code.
Your code may need following function:
#Override
protected void onProgressUpdate(Integer a) {
super.onProgressUpdate(a);
}
Override the function instead of just copy past,
use keyword #Override
I am calling a web service using AsyncTask in a android app and I can not figure out how to wait until the onPostExecute has finished:
//Call Async Web Service here
AsyncCallWS task = new AsyncCallWS();
task.execute();
//Need to wait to fill this in ** Its not waiting.
String sCall = rslt;
String[] aCall = sCall.split("//|");
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
#Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
GetURL();
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
try{
//Results HERE
rslt = resultString.toString();
}
catch(Exception ex)
{rslt = ex.toString()+ "|" + ex.toString();}
}
}
I'm not clear on what you can't/don't want to do from onPostExecute but you can use a callback if you are wanting to execute something that's not coupled to the task (so that you can run the task from anywhere)
private class OnFinishedListener {
void onFinished(String rslt);
}
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
private OnFinishedListener mAfter;
public AsyncCallWS(OnFinishedListener after) {
mAfter = after;
}
...
#Override
protected void onPostExecute(Void result) {
....
if (mAfter != null) {
//you didnt illustrate what resultString is, you might
//want this to be the returned value from doInBackground
mAfter.onFinished(resultString.toString());
}
}
}
Usage
new AsyncCallWS(new OnFinishedListener {
public void onFinished(String rslt) {
//for example
String sCall = rslt;
String[] aCall = sCall.split("//|");
}
}).execute();
You can use Tasks.await(task) in a background thread. Do not use this in UI thread. You can also set timeout for your task Tasks.await(task, 500, TimeUnit.MILLISECONDS);
Use the getStatus() method.
while (task.getStatus() != Status.FINISHED);
A better way to do this would be to call split() inside the onPostExecute() method, since onPostExecute() runs on the UI thread anyway and the while() call would block the current thread it's running in.
I am new to android programming. I am developing a web crawler for which i am using a Async Task and it is working well.In order to keep user informed,i am using progress dialog. My problem is,if i use a Progress Dialog my program takes more time to execute and when i won`t use the progress dialog,it executes faster.
Done Work
OnCreate Method
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results);
Intent intent = getIntent();
s1 = intent.getStringExtra("Number1");
s2 = intent.getStringExtra("Number2");
s3=intent.getIntExtra("selectedItem",0);
HttpAsyncTask asyncTask = new HttpAsyncTask();
asyncTask.execute();
}catch (Exception e)
{
messageBox("Exception",e.getMessage());
}
}
Async Task Class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private ProgressDialog dialog;
#Override
protected void onPreExecute()
{
dialog = new ProgressDialog(Results.this);
dialog.setIndeterminate(true);
dialog.setMessage("Please Wait");
dialog.setCancelable(true);
dialog.show();
super.onPreExecute();
}
#Override
protected List<String> doInBackground(List<String>... urls) {
//android.os.Debug.waitForDebugger();
// spinner.setVisibility(View.VISIBLE);
List<String>resultList=new ArrayList<String>();
try
{
if(isCancelled())
return resultList;
resultList=WebCrawlerClass.GetPost(s1,s2,s3);
}catch (Exception e)
{
messageBoxs("Error", e.getMessage());
}
return resultList;
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(List<String> result)
{
if(dialog.isShowing())
{
dialog.dismiss();
}
if(s3 == 2)
{
docListAdapter=new ListViewData(Results.this,result);
}
else {
docListAdapter = new NameNumListData(Results.this, result);
}
docList=(ListView)findViewById(R.id.listView2);
docList.setAdapter(docListAdapter);
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
super.onCancelled();
this.cancel(true);
}
}
Am I missing something? Need help..
Thanks and Regards,
Abhinav
In you activity
// Start the progress dialog
..
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// dismiss the progress dialog
}
};
HttpAsyncTask asyncTask = new HttpAsyncTask(handler);
asyncTask.execute();
In your asynctask class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private Handler handler = null;
public HttpAsyncTask (Handler handler) {
this.handler = handler;
}
protected Void doInBackground(Void... params) {
//Perform your task
// When you know that task is finished , fire following code
if (null != handler) {
Message message = handler.obtainMessage();
message.obj = Any data you want to sent to the activity
message.what = 1 ; ( Optional )
handler.sendMessage(message);
}
}
Thus when sendMessage function is called from doInbackground.. your handleMessage in your activity will get triggered and then you should dismiss the progress dialog
Hope this will improve the performance issue what you are facing
Remove super.onPreExecute(); in onPreExecute() method and check .It might Help
So I have created a webservice call class that calls my webservice which extends on AsyncTask:
public class WebServiceLoginCall extends AsyncTask{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
protected void onPostExecute(Void result) {
try {
if(loginStatus){
System.out.println("onpost has been executed");
//Navigate to Home Screen
loginIntent = new Intent(getBaseContext(), HomeActivity.class);
startActivity(loginIntent);
//prevents user to go back to the login screen
finish();
}else{
//Set Error message
Toast.makeText(getApplicationContext(), "Login Failed. Check your details.", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "An error occured. Check your mobile connection.", Toast.LENGTH_SHORT).show();
}
}
#Override
protected Boolean doInBackground(Object... arg0) {
System.out.println("doinbackground triggered");
try {
loginStatus = Webservice.invokeLoginWS(loginUser.get_userEmail(), loginUser.get_userPassword());
} catch (Exception e) {
System.out.println("an error occured with the webservice");
}
return loginStatus;
}
}
When the user presses the login button, I use the following code:
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnLogin:
email = (EditText) findViewById(R.id.txtEmail);
loginUser = new User();
loginUser.set_userEmail(email.getText().toString());
loginUser.set_userPassword(password.getText().toString());
//starts loging webservice
WebServiceLoginCall task = new WebServiceLoginCall();
//executes the login task
task.execute();
break;
When I check, the doInBackground is triggered in my console, but the onPostExecute is not. Is there anything that I am doing wrong? The doInBackground does not throw any exceptions.
Make following two changes
1.Use public class WebServiceLoginCall extends AsyncTask<Void, Void, Boolean >
instead of public class WebServiceLoginCall extends AsyncTask
2.Use
#Override
protected void onPostExecute(Void result) {
// your code
}
instead of just
protected void onPostExecute(Void result) {
// your code
}
Refer Android- Async task
Explanation:
In your case if you put #Override on onPostExecute() without extending the generic Asynctask, you will get a compile time error. Hence you will have to make above two changes.
hope it helps you.
because you are calling a different method your post execute wont execute ever execute if you defined it like your code
use
#Override
protected void onPostExecute(boolean result) {
}
Because your not Override the onPostExecute() method
add : #Override
like this
#Override
protected void onPostExecute(Void result) {
try {
if(loginStatus){
System.out.println("onpost has been executed");
//Navigate to Home Screen
loginIntent = new Intent(getBaseContext(), HomeActivity.class);
startActivity(loginIntent);
//prevents user to go back to the login screen
finish();
}else{
//Set Error message
Toast.makeText(getApplicationContext(), "Login Failed. Check your details.", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "An error occured. Check your mobile connection.", Toast.LENGTH_SHORT).show();
}
}
1) Add the #Override to your postexecute
2) If your asynctask takes parameter then execute your asynctask like this:
task.execute(Object);
because your AsyncTask takes Object
#Override
protected Boolean doInBackground(Object... arg0)
3) Your doInBackground returns a Boolean loginStatus value but your onPostExecute(Void result) takes in void.
Hope it helps
I am trying to make it so that when the user pushes a button than it cancels the Asynk task and then finishes the activity but i keep getting errors with the "MyAsyncTask.cancel(true);" if there is additional info you need please tell me.
here is what I got,
class MyAsyncTask extends AsyncTask<Void, Integer, Void>{
boolean DoingSomething;
int progress_status;
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.v("UpGradeRep", "started");
DoingSomething = true;
UpGradeRep.setVisibility(View.GONE);
UpGradeRepDis.setVisibility(View.GONE);
Toast.makeText(MainActivity.this,
"started", Toast.LENGTH_SHORT).show();
// progress_status = 0;
}
#Override
protected Void doInBackground(Void... params) {
while (!isCancelled()) {
while(DoUpCount==true){
progress_status += 1;
publishProgress(progress_status);
SystemClock.sleep(200);
if(isCancelled()){
break;
}
}
}
return null;
}
int UpGradRepcounter = 0;
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
UpGradRepcounter++;
DevUpCountDis.setText(" "+UpGradRepcounter);
Money = Money +inc;
MoneyDis.setText("$"+Money);
}
#Override
protected void onCancelled() {
Toast.makeText(getApplicationContext(), "Canceled", Toast.LENGTH_SHORT);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
DoUpCount=false;
DoingSomething = false;
Log.v("UpGradeRep", "Done");
}
}
here's what i do when i am trying to close it
Statistics.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
MyAsyncTask.cancel(true);
//^^^^Right here is where it tells me "Cannot make a static reference to the non-static method cancel(boolean) from the type AsyncTask<Void,Integer,Void>"
Intent GoToStatistics = new Intent(getApplicationContext(),statistics.class);
GoToStatistics.putExtra("LittleHelper", LittleHelper);
startActivity(GoToStatistics);
finish();
}
});
so thats the code i set up to do what i whant and it dose good but when i leave it gives a frame drop warning in my Logcat so i was ausuming that im not closeing it properly
im starting it like this
so when the user pushes the button than it starts it
UpGradeRep.setOnClickListener(new View.OnClickListener() {
#SuppressWarnings("unchecked")
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (Money>=upGM2) {
LittleHelper=true;
DoUpCount=true;
Log.v("DoUpCount"," "+DoUpCount);
(new MyAsyncTask()).execute();
}else{
Error.setText("you need more money.");
}
}
});
You're trying to call a metod over a non-static object within a static context (the onClick()) event. Basically what that error is telling you is that you must make your AsyncTask object static in order to be able to call the cancel() method over it.
This is as "easy" as declaring your AsyncTask as static, but that could generate some other compilation errors over your AsyncTask object, and you'll have to be very thorough to avoid possible memory leaks.
The method cancel(boolean mayInterruptIfRunning) (in class AsyncTask) is not a static method and you're calling it with the class name (the way static methods are invoked).
You should use the instance of MyAsyncTask to call (this):
this.cancel(true);