I have used Async Task many times but I am facing this type of problem for the first time. I searched Stack Overflow but couldn't find any useful solution.
My issue is onPostExecute is not getting called in Async task, All operations that are in doinbackground are completed but control is not reaching the onPostExecute... not able to understand the reason.
Code:
public class deletedaily extends AsyncTask<Void , Void, long[]>{
ProgressDialog pd;
long resultdelete;
protected void onPreExecute(){
pd=new ProgressDialog(StockDetail.this);
if(pd!=null){
pd.setMessage("Deleting data.....please wait");
pd.show();
}
}
protected long[] doInBackground(Void... params) {
// TODO Auto-generated method stub
try{
Database.getInstance(getApplicationContext()).getWritableDatabase().beginTransaction();
resultdelete = Database.getInstance(getApplicationContext()).getWritableDatabase().delete(st.tablename, st.column2 + "=? AND " + st.column3 + "=?", new String[] {getdailydate.toString(),stockname} );
Database.getInstance(getApplicationContext()).getWritableDatabase().setTransactionSuccessful();
new popdailydata().execute(); //here calling list view to populate after deletion
}
catch(Exception dailydeleteerror){}
finally{
Database.getInstance(getApplicationContext()).getWritableDatabase().endTransaction();
}
return new long[] {resultdelete};
}
protected void onPostExecute(long result){
System.out.println("postexecute entered");
if(pd!=null){
pd.dismiss();
}
if(result!=-1){
Toast.makeText(getApplicationContext(),"Date deleted from your portfolio", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(),"Failed to delete ....try again", Toast.LENGTH_LONG).show();
}
}
}
Edit
I am calling from onclick of Image buton
deletedailydata.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new deletedaily().execute();
}
});
It should be onPostExecute(long [] result).
You extended your class like AsyncTask<Void , Void, long[]>. This means that the return value of doInBackground will be long[] and the parameter of onPostExecute also. As what you get in onPostExecute is the result returned by doInBackgroud the type should be the same.
Related
There are two Activities. The first Activity is having the list view to see what is being shared and the second activity has an edit text box (to input inorder to share) and a button. On clicking the button, it returns me the string which is the json response and I need to add this in the previous activity.
Now the problem is, when I refresh the first page fully hitting the server it gets the response but this is not what I want. It should not go back to the server. It should simply add in the list view adapter.
I have commented the code in the PostExecute(). I have tried the everyway but it is not reflecting. I am also posting my code for your reference.
public class ShareAsyncTask extends AsyncTask<String, Void, ArrayList<EventsStreamBean>> {
public ProgressDialog pd = new ProgressDialog(EventStreamActivity.this);
String success_share_val;
#Override
protected ArrayList<EventsStreamBean> doInBackground(
String... result) {
// TODO Auto-generated method stub
JSONObject jsonobj = new JSONObject(result[0].toString());
success_share_val = jsonobj.getString(Constants.SUCCESS);
//checks the success value
if(success_share_val.equalsIgnoreCase("1")) {
JSONArray events_stream_share_array = jsonobj.getJSONArray("streamArray");
if(events_stream_share_array.length() > 0) {
for(int i=0; i<events_stream_share_array.length(); i++) {
EventsStreamBean events_stream_bean = new EventsStreamBean();
JSONObject events_stream_object = events_stream_share_array.getJSONObject(i);
events_stream_bean.setStreamId(events_stream_object.getString(Constants.STREAM_ID));
events_stream_bean.setStreamType(events_stream_object.getString(Constants.STREAM_TYPE));
events_stream_bean.setUserId(events_stream_object.getString(Constants.USER_ID));
events_stream_bean.setUserName(events_stream_object.getString(Constants.USER_NAME));
events_stream_bean.setUserType(events_stream_object.getString(Constants.USER_TYPE));
events_stream_bean.setUserAvatar(events_stream_object.getString(Constants.USER_AVATAR));
arraylist_events_stream.add(events_stream_bean);
}
}else {
Log.i("Test", "No Events Streams Available");
}
}
}catch(Exception e) {}
return arraylist_events_stream;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
this.pd.setMessage("Loading....");
pd.setCanceledOnTouchOutside(false);
pd.setCancelable(false);
this.pd.show();
}
#Override
protected void onPostExecute(final ArrayList<EventsStreamBean> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(this.pd.isShowing()) {
this.pd.dismiss();
}
Toast.makeText(EventStreamActivity.this, "Post shared successfully", Toast.LENGTH_SHORT).show();
new EventsStreamAsyncTask().execute(temp_val);
/*runOnUiThread(new Runnable() {
public void run() {
//EventStream_Customadapter adapter = (EventStream_Customadapter) list_view.getAdapter();
//adapter.clearData();
adapter.updateData(result);
//adapter = new EventStream_Customadapter(EventStreamActivity.this, arraylist_events_stream);
//list_view.setAdapter(adapter);
//adapter.notifyDataSetChanged();
}
});*/
}
}
Thank you
I have following 2 class
class CallNetworkMethod extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... params) {
if (TwitterUtils.isAuthenticated(prefs)) {
sendTweet();
} else {
Intent i = new Intent(getApplicationContext(), TwPrepareRequestTokenActivity.class);
i.putExtra("tweet_msg",getTweetMsg());
startActivity(i);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//updateLoginStatus();
loginStatus.setText("Logged into Twitter : " + TwitterUtils.isAuthenticated(prefs));
}
}
====================================================
public class TwitterUtils {
static ArrayList<String> friens=null;
public static boolean isAuthenticated(SharedPreferences prefs) {
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
AccessToken a = new AccessToken(token,secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(TwConstants.CONSUMER_KEY, TwConstants.CONSUMER_SECRET);
twitter.setOAuthAccessToken(a);
try {
**twitter.getAccountSettings();**
return true;
} catch (TwitterException e) {
return false;
}
}
}
I got the exception when running this code(networkonmainthreadexception).I debug this code and found the location where exception come out. It is twitter.getAccountSettings(); .I think this method should run inside a AsynTask but i dont know how to do that.
Currently you are calling TwitterUtils.isAuthenticated(prefs) in onPostExecute because onPostExecute always execute on UI thread then you are getting networkonmainthreadexception exception .
to avoid this issue use a Boolean Flag to get return from doInBackground and show it in TextView in onPostExecute as:
class CallNetworkMethod extends AsyncTask<Void, Void, Void>
{
public static boolean status=false;
#Override
protected Void doInBackground(Void... params) {
status=TwitterUtils.isAuthenticated(prefs);
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//updateLoginStatus();
loginStatus.setText("Logged into Twitter : " + status);
}
}
the problem is that you're using the AsyncTask wrong.
The idea for the onBackground returning a value and the onPostExecute receiving a result is to pass to the UI thread something that was done on the background thread.
Something like that:
change the class CallNetworkMethod extends AsyncTask<Void, Void, Void> to
class CallNetworkMethod extends AsyncTask<Void, Void, Boolean>
change the protected Void doInBackground(Void... params) { to
protected Boolean doInBackground(Void... params) {
Boolean result = TwitterUtils.isAuthenticated(prefs);
if (result) {
sendTweet();
} else {
Intent i = new Intent(getApplicationContext(), TwPrepareRequestTokenActivity.class);
i.putExtra("tweet_msg",getTweetMsg());
startActivity(i);
}
return result;
}
and change the protected void onPostExecute(Void result) { to
protected void onPostExecute(Boolean result) {
loginStatus.setText("Logged into Twitter : " + result.toString());
}
Note that this method blocks waiting for a network response, so do not call it in a UI thread.
This is what is suggested when using:
facebook.request("me");
Same might be the case with:
twitter.getAccountSettings();
So, just like other Network connections, which you call using AsyncTasks, call this in some AsyncTask.
Okay, the Error might be here:
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//updateLoginStatus();
loginStatus.setText("Logged into Twitter : " + TwitterUtils.isAuthenticated(prefs));
}
You are calling TwitterUtils.isAuthenticated(prefs) in onPostExecute();
Your first call to isAuthenticated() is correctly placed in the AsyncTask. However, when you use:
loginStatus.setText("Logged into Twitter : " + TwitterUtils.isAuthenticated(prefs));
in your onPostExecute(), you're calling a networking method on the UI thread again, as onPostExecute() is run on the UI thread.
Remove this line, or store the result locally from doInBackground() and use it here.
I want to load datas from a list to gridview with a loading effect using progressbar.Im getting items from a webservice.The problem i face is im unable to dismiss the progress bar even after showing the gridview.I can see the gridview with items but progress bar is still running .What am i doing wrong here.
private void testAsyncTask() {
Log.e("Im in testAsyncTask()", "");
new AsyncTask<Object, Object, Object>() {
#Override
protected void onPreExecute() {
progress_Dialog = ProgressDialog.show(a, "", "Loading");
Log.e("Im in onPreExecute", "");
// super.onPreExecute();
}
#Override
protected Integer doInBackground(Object... params) {
MenuService menuService = new MenuServiceImpl();
PartnerMenuServiceResponse partnerMenu = menuService
.getPartnerMenu();
jewellist = partnerMenu.getMenu().getMenuEntries();
Log.e("Im in doInBackground", "");
System.gc();
return 0;
}
#Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
// super.onPostExecute(result);asd
Log.e("Im in onPostExecute", "");
if (progress_Dialog.isShowing()) {
progress_Dialog.dismiss();
}
ShopGridAdapter adapter = new ShopGridAdapter(ShopGridActivity.this, jewellist);
AllJewelgridView.setAdapter(adapter);
adapter.notifyDataSetChanged();
//AllJewelgridView.setAdapter(new ShopGridAdapter(
// ShopGridActivity.this, jewellist));
if (AllJewelgridView.getCount() <= 0) {
MyAlertDialog.ShowAlertDialog(ShopGridActivity.this, "",
"No data found.", "OK");
}
progress_Dialog.dismiss();
}
}.execute();
}
#Override
protected void onPreExecute() {
progress_Dialog = new ProgressDialog(context);
progress_Dialog.setMessage("Loading...");
progress_Dialog.show();
}
EDIT :
#Override
protected void onPostExecute(Object result) {
Log.e("Im in onPostExecute", ""); <------ ARE YOU ABLE SEE THIS IN logcat ?
progress_Dialog();
}
It may possible onPostExecute() not called. So to confirm check logcat
You need to put some code in your AsyncTask
ProgressDialog progress=null;
progress=ProgressDialog.show(this,"title","loading..").show();//put this code in onPreExecute()
progress.dismiss();//put this code in onPostExecute()
for more ProgressBar while loading ListView (using AsyncTask)
You can write in onPostExecute method may help you.
if ( progress_Dialog != null) {
progress_Dialog.cancel();
}
I am implementing AsyncTask for my understanding of concepts. The code is working but not in way I want to. I have gone through the documents but cannot pin point what wrong am I doing.
Code:
private class NewThread extends AsyncTask<Integer, Integer , String>
{
#Override
protected String doInBackground(Integer... params) {
Log.d(TAG,"inside doInBackground");
for (int i=0;i<params.length;i++)
{
try {
publishProgress(i);
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return "Finished";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getBaseContext(), result, Toast.LENGTH_SHORT).show();
Log.d(TAG,"inside onPostExecute");
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
Toast.makeText(getBaseContext(), "Done " + values[0], Toast.LENGTH_SHORT).show();
Log.d(TAG,"inside onProgressUpdate");
}
I only see Done 0 and Finished. What I was expecting is Done0 , Finished, Done1, Finished, Done2. Finished.... OR Done0 Done1 Done2 ....Finished.
What should I change in code to do that? Is it even possible?
I am calling AsyncTask using a button.
public void onClick(View v) {
// TODO Auto-generated method stub
new NewThread().execute(4);
}
Thanks
The code you use to start the AsyncTask starts 1 (one) instance, passing 4 as a parameter. Therefore, param.length() is 1 (one) and you get only one output.
Try this instead:
new NewThread().execute(1,2,3,4);
Or maybe this, if you want to see several threads working simultaneously:
new NewThread().execute(1);
new NewThread().execute(2);
new NewThread().execute(3);
Without seeing your code to call the a sync task this is just a guess. Looks like you aren't using the params value quite right. It should be:
for(int i = 0; i < params[0]; i++)
Change this:
#Override
protected String doInBackground(Integer... params) {
Log.d(TAG,"inside doInBackground");
for (int i=0;i<params.length;i++)
to
#Override
protected String doInBackground(Integer myCount) {
Log.d(TAG,"inside doInBackground");
for (int i=0;i<myCount;i++)
Async task is correctly executed. You are passing an array with one item and in the loop you are checking for the lenth of the array which is 1 so you get only one "print".
Either in the loop replace
Also one more minor mistake, you expect done 0, done 1 .. to be printed .
But your statement is "Done " + values[0] , which will always print the same statement :)
Okay, this has me confused once again. I am trying to either A: set a golbal variable, which i can do or B: retieve a variable from my AsyncTask. I have set can set the golbal variable from asynctask which is fine, but the activity calls it before it is set with the asynctask.
So therefore I need the application to finsh the AsyncTask before calling the golbal variable.
new createUser().execute();
Log.i("res", "After: " + Boolean.toString(MyProperties.getInstance().valut));
private class createUser extends AsyncTask<Void, Void, Boolean> {
ProgressDialog dialog = ProgressDialog.show(MainActivity.this, "",
"Creating User...", true);
Toast toast = Toast.makeText(getApplicationContext(), "",
Toast.LENGTH_SHORT);
#Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
if (db.createUser(nameU.getText().toString(), userU.getText()
.toString(), emailU.getText().toString(), passU.getText()
.toString()) == false) {
return false;
} else {
return true;
}
}
protected void onPreExecute() {
dialog.show();
}
protected void onPostExecute(Boolean result) {
dialog.dismiss();
if (!result) {
toast.setText("User already exists!");
toast.show();
res = result;
MyProperties.getInstance().valut = res;
Log.i("res", Boolean.toString(MyProperties.getInstance().valut));
} else {
toast.setText("Success");
toast.show();
res = result;
MyProperties.getInstance().valut = res;
Log.i("res", Boolean.toString(MyProperties.getInstance().valut));
}
}
}
Work with your global variable in onPostExecute method of your AsyncTask. You need to implement it in your AsyncTask's child. This method is called then all work is done.
EDIT
private class createUser extends AsyncTask<Void, Void, Boolean> {
ProgressDialog dialog;
#Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
if (db.createUser(nameU.getText().toString(), userU.getText()
.toString(), emailU.getText().toString(), passU.getText()
.toString()) == false) {
return false;
} else {
return true;
}
}
protected void onPreExecute() {
dialog = ProgressDialog.show(MainActivity.this, "", "Creating User...", true);
dialog.show();
}
protected void onPostExecute(Boolean result) {
dialog.dismiss();
Toast.makeText(
getApplicationContext(),
result?"Success":"User already exists!",
Toast.LENGTH_SHORT).show();
MyProperties.getInstance().valut = result
Log.i("res", Boolean.toString(MyProperties.getInstance().valut));
}
}
Two issues:
Java does not really have any global variables. The closest it has are static class variables. Since you haven't shown your declared variable, I can't say what you've really implemented.
Every AsyncTask has a onPostExecute(..) method you can override that runs in the original thread/Looper after doInBackground(..) has completed. Override this to do things like Update the UI thread.