Behavior of AsyncTask - android

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 :)

Related

onPostExecute is not getting called after successful completion of doinbackground

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.

Changing text of text view repeatedly in an order

I have three strings
String one="Connecting.";
String two="Connecting..";
String three="Connecting...";
I have a textView, what I want is to set text to textview in this order..
one-->two-->three-->one-->two-->three and so on until the process is completed.
I have done it in a for loop based on value i.e
if(value%3==0){
tx.setText(one);
}
else if(value%3==1){
tx.setText(two);
}
else
{
tx.setText(three);
}
This is done inside a thread and it is working well.
But I dont want to rely on "value".. I jst want that until process is completed the text changes in order as mentioned above.
I know it is vague but I am not getting how to do this.
Please if someone can give any hint.
code:
public void startProgress(View view) {
bar.setProgress(0);
tx.setText("Connect");
new Thread(new Task()).start();
}
class Task implements Runnable {
#Override
public void run() {
for (int i = 0; i <= 10; i++) {
final int value = i;
try {
Thread.sleep(500);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
bar.setProgress(value);
String one="Connecting.";
String two="Connecting..";
String three="Connecting...";
if(value%3==0){
tx.setText(one);
}
else if(value%3==1){
tx.setText(two);
}
else
{
tx.setText(three);
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
It makes sense to have a counter like value that keeps incrementing. But you could do it a little more simply:
String[] texts = new String[3] {"Connecting.", "Connecting..", "Connecting..."};
int value = 0;
// ...
tx.setText(texts[value]);
value = (value+1)%3;
This way, you don't need your big messy if statement. You will need to find another way of notifying your thread when the job is done, rather than just having a fixed number of iterations.
Use TextSwitcher instead of TextView...It will work

my application not read if statement in postexecute method

my code will crash if i not comment statement else if (message.equals("holiday")) on postexecute tell me why is not go further if not euqal this line (message.equals("holiday")) why not print "School is off today. Reason: if i comment else if (message.equals("holiday")) this code app work fine check my if else stateement please
String message;
public class getDataTask extends AsyncTask<Void, Void, Void> {
getDataTask() {
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
yourBoolean=false;
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
displayData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
yourBoolean=true ;
if ((Category_ID.size() > 0) ) {
listCategory.setAdapter(cla);
cla.notifyDataSetChanged() ;
listCategory.invalidateViews();
menu_nametxt.setText(mVal2);
}
else if (message.equals("holiday"))
{
menu_nametxt.setText("No menu available .");
listCategory.setVisibility(View.GONE);
}
else
menu_nametxt.setText("School is off today. Reason: "+mVal3);
listCategory.setVisibility(View.GONE);
}
private void displayData() {
Cursor mCursor3 = db.selectQuery("SELECT * FROM uss_vacation WHERE calendar_id);
if (mCursor3.moveToFirst()) {
do {
Vacation_Date.add(mCursor3.getString(mCursor3.getColumnIndex("date")));
if(mCursor3.getString(mCursor3.getColumnIndex("date")).equals(mydate))
{
message = "holiday";
String mVal ;
mVal = (mCursor3.getString(mCursor3.getColumnIndex("title")));
mVal2 = mVal.toString();
mCursor3.close();
return;
}
} while (mCursor3.moveToNext());
}
mCursor3.close();
}
if i comment this code application print "School is off today. Reason: text
else if (message.equals("holiday"))
// {
// menu_nametxt.setText("No menu available .");
// listCategory.setVisibility(View.GONE);
// }
Since message is null when the app is run for the first time, when the if-else statement reaches else if (message.equals("holiday"), it will throws NullPointerException instead of false and crashing the app.
see SO: Java null String equals result
Consider initialize the message with empty string instead. (i.e. message = "";).
OR
Change the order of checking to else if ("holiday".equals(message)).

How to refresh a listview in android using asynctask?

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

android AsyncTask - can't execute onPostExecute method

I have wrote an app to run an AsyncTask and part of the code is listed as follow. The problem is when the AsyncTask start by execute the code - "new AddImageTask().execute();" in the thread handler, the task will start and everything seems right. However, eventually the app will stay in "doInBackground" method after all code in "doInBackground" method has been executed. The task can't go to "onPostExecute" method. (i.e. can't dismiss the dialog...) What get wrong?
Thanks for the help......
private Handler handleFetchResult = new Handler() {
#Override
public void handleMessage(Message msg) {
progressDialog.dismiss();
Log.d(TAG, "Start handle fetch result");
try {
JSONArray ja = new JSONArray(fetchResult);
Log.d(TAG, "JSON Array Length = " + ja.length());
JSONObject jo = new JSONObject();
for (int i = 0; i < ja.length(); i++) {
jo = ja.getJSONObject(i);
PhotoURLs.add(PAT_url + jo.getString("filePath"));
Log.d(TAG, PhotoURLs.get(i));
}
} catch (JSONException e) {
Log.d(TAG, "Fetch result error: " + e.getLocalizedMessage());
e.printStackTrace();
}
//TODO: display thumbnail
new AddImageTask().execute();
}//void handleMessage
};//Handler handleFetchResult
class AddImageTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
loadThumbnailDialog.show(SitePhotoGallery.this, "Fetch thumbnails from server",
"Loading...", true, true);
Log.d("AddImageTask.onPreExecute","onPreExecute");
}
#Override
protected Void doInBackground(Void... unused) {
// TODO Auto-generated method stub
for (String url : PhotoURLs) {
String filename = url.substring(url.lastIndexOf("/") + 1, url.length());
String thumburl = url.substring(0, url.lastIndexOf("/")+1);
imgAdapter.addItem(LoadThumbnailFromURL(thumburl + filename));
publishProgress();
}
Log.d("AddImageTask.doInBackground","doInBackground");
return null ;
}
#Override
protected void onProgressUpdate(Void... unused) {
super.onProgressUpdate();
imgAdapter.notifyDataSetChanged();
Log.d("AddImageTask.onProgressUpdate","OnProgressUpdate");
}
protected void onPostExecute(Void... unused) {
super.onPostExecute(null);
loadThumbnailDialog.dismiss();
Log.d("AddImageTask.onPostExecute","onPostExecute");
}
}
I think it's because onPostExecute() should take a Void parameter and not a Void... parameter. (You should also specify #Override as Soxxeh pointed out in his/her comment above.)

Categories

Resources