I would like to show ProgressDialog during another asynctask.
I write ProgressDialog . one AsyncTask
and I write another AsyncTask in PostExecute method.
but ProgressDialog doesn't run... I'd appreciate your kind help.
AsyncTask code:
public class SavingProgressTask extends AsyncTask<Void, Void, Void> {
private Context mContext;
private ProgressDialog progDialog = null;
public SavingProgressTask(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progDialog = new ProgressDialog(mContext);
progDialog.setMessage("saving...");
progDialog.setIndeterminate(false);
progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progDialog.setCancelable(false);
progDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(isUpdateStore) {
try {
int storeResponseMessage = new StoreUpdateTask(SettingActivity.this).execute(fc_code).get();
if(storeResponseMessage == 1) {
Store updateStore = new StoreDetailTask(SettingActivity.this, false).execute(fc_code).get();
mAuthUser.setStore(updateStore);
UserAuthUtil.saveUserObject(SettingActivity.this, mAuthUser);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
int userinfoResponseMessage;
int userinfosex;
if(mSexTextView.getText().toString().equals("남자")) {
userinfosex = 1;
} else if (mSexTextView.getText().toString().equals("여자")){
userinfosex = 2;
} else {
userinfosex = 2;
}
if(isUpdateBirthday) {
if(isUpdateSex) {
try {
userinfoResponseMessage = new UserUpdateTask(SettingActivity.this, true, "TWICE").execute(tempBirthDay, String.valueOf(userinfosex)).get();
if(userinfoResponseMessage == 1) {
mAuthUser.getUser().setBirthday(tempBirthDay);
mAuthUser.getUser().setSex(userinfosex);
UserAuthUtil.saveUserObject(SettingActivity.this, mAuthUser);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
try {
userinfoResponseMessage = new UserUpdateTask(SettingActivity.this, true, "BIRTHDAY").execute(tempBirthDay).get();
if(userinfoResponseMessage == 1) {
mAuthUser.getUser().setBirthday(tempBirthDay);
UserAuthUtil.saveUserObject(SettingActivity.this, mAuthUser);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
} else {
if(isUpdateSex) {
try {
userinfoResponseMessage = new UserUpdateTask(SettingActivity.this, true, "SEX").execute(String.valueOf(userinfosex)).get();
if(userinfoResponseMessage == 1) {
mAuthUser.getUser().setSex(userinfosex);
UserAuthUtil.saveUserObject(SettingActivity.this, mAuthUser);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
}
}
if(progDialog != null) {
progDialog.dismiss();
Intent intent = new Intent(mContext, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
mContext.startActivity(intent);
}
}
in click listener:
SavingProgressTask saveTask = new SavingProgressTask(SettingActivity.this);
saveTask.execute();
As far as I know starting another async task from the post execute of previous async task is not that good idea.
When I had a similar problem in one of my projects I had followed the following process.
1) Create an interface with a method like notifyUIThread().
2) Implement this interface from the activity, which calls the async task.
3) While creating the async task, pass 'this' as a parameter to the constructor of the async task.
4) In the post execute of async task call the this.notifyUIThread() method.
5) In the overridden method notifyUIThread(), make a call to the next async task.
Coming to the progress dialog, make it global variable, show it in the pre execute method of the first async task, dismiss it in the post execute of the second async task.
You can also do make the progress dialog local to the async task, show in pre execute and dismiss in post execute of both the async tasks.
But a small advice here is, keep the app responsive. Showing the progress dialog for a long time is not advisable.
Related
I'm using OSMdroid Mapview and using AsyncTask class to get some data, and I create overlays and try to redraw every time I get a msg.
Unfortunately I'm able to get data from a client and I'm able to create overlays to in onProgressUpdated, I've even called invalidate(); But nothing seems to happen. Not sure what is the problem?
Here's my AsyncTask:
public class TaskManager extends AsyncTask<Void, GeoPoint, Void>{
.....
public TaskManager(Master master,MapView mapview) {
//Construtor
}
#Override
protected Void doInBackground(Void... arg0) {
if(Constance.TCPIP) {
Log.d("APP","Inside TCPIP");
//Creation of TCPIP Sockets
try {
m_ssocket = new ServerSocket(Constance.PORT_NO);
Log.d("APP","ServerSocket: "+m_ssocket);
m_socket = m_ssocket.accept();
Log.d("APP","Accepted: "+m_socket);
} catch (IOException e) {
e.printStackTrace();
}
}
else if (Constance.UDPIP) {
//Creation of UDP Sockets
try {
m_dsocket = new DatagramSocket(Constance.PORT_NO);
} catch (SocketException e) {
e.printStackTrace();
}
}
else if (Constance.MCUDP) {
//Lock Wifi multicast
mMultiCastLock = new MultiCastLock(mMaster.getBaseContext());
mMultiCastLock.setMultiCastAcquire();
//Creation of MC-UDP Sockets
try {
m_mcsocket = new MulticastSocket(Constance.PORT_NO);
InetAddress address = InetAddress.getByName(Constance.GROUP_ADDR);
m_mcsocket.joinGroup(address);
} catch (IOException e) {
e.printStackTrace();
}
}
// Create a buffer to read datagrams into.
byte[] mSocketbuffer = new byte[Constance.DGRAM_LEN];
if(Constance.TCPIP) {
try {
m_inSocketData = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));
Log.d("APP","Reading");
} catch (IOException e) {
e.printStackTrace();
}
} else {
// Create a packet to receive data into the buffer
m_inPacket = new DatagramPacket(mSocketbuffer, mSocketbuffer.length);
}
//prepare overlay items
prepareItemizedOverlay();
// Now loop forever, waiting to receive packets and printing them.
if(m_ssocket!=null || m_dsocket!=null || m_mcsocket!=null)
while (true) {
if (isCancelled()) break;
//Get Data
parseData();
//Make Packet Object
if(mMSG!=null) {
make(mMSG);
}
if(m_inPacket!=null && !Constance.TCPIP) {
// Reset the length of the packet before reusing it.
m_inPacket.setLength(mSocketbuffer.length);
}
}
return null;
}
#Override
protected void onProgressUpdate(GeoPoint... geoPoints){
OverlayItem overlayItem = new OverlayItem("Name", "Description", geoPoints[0]);
mItemizedOverlay.addOverlay(overlayItem);
mMapView.getOverlays().add(mItemizedOverlay);
mMapView.getController().animateTo(geoPoints[0]);
mMapView.invalidate();
}
#Override
protected void onCancelled() {
super.onCancelled();
if(Constance.TCPIP) {
if(m_ssocket!=null && m_socket!=null){
try {
m_ssocket.close();
m_socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else if(Constance.UDPIP) {
if(m_dsocket!=null)
m_dsocket.close();
} else if(Constance.MCUDP) {
if(m_mcsocket!=null)
m_mcsocket.close();
}
Log.d("APP","Task Ended");
}
private void parseData() {
if(Constance.TCPIP) {
// Wait to receive a socket data
try{
mMSG = m_inSocketData.readLine();
} catch (IOException e) {
e.printStackTrace();
}
} else {
// Wait to receive a datagram
try {
m_dsocket.receive(m_inPacket);
// Convert the contents to a string, and display them
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void make(String plot) {
//Make Object
mMSG = new MSG(plot);
//Overlay
mGeoPoint = mMSG.getGeoPoint();
publishProgress(mMSG.getGeoPoint());
}
private void prepareItemizedOverlay() {
/* itemized overlay */
Drawable newMarker = mMaster.getResources().getDrawable(R.drawable.ic_sensor);
mItemizedOverlay = new PlotItemOverlay(mMaster,mItemList,newMarker,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(int index, OverlayItem item) {
Log.d("APP","HERE");
return true;
}
#Override
public boolean onItemLongPress(int index, OverlayItem item) {
return true;
}
}, mResourceProxy);
}
}
Everything seems to work, but nothing seems to happen, not sure what is the problem?
Finally resolved it. I was actually replacing my MapFragment class which led to all this loss of Object and a new object created was interfacing the old one, and so the data received to interfacing to the older MapFragment and not the new MapFragment. Got it resolved, once I found the logically analyzing the code. Anyways, thanks for the support #kurtzmarc you have been very helpful until now. I will continue same with OSMdroid to see any more things that I come up with.
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.
i have created one simple login application which takes user name and password from sqlserver..it works fine...
i want during login process one progeress bar should be displayed using asyntask...
but i am unaware to use parameters in asyntask...if some one plzz tell me how to put my method in doInbackground of asyntask and what param should i use....
my code is;.....
public void save(){
initilize();
ResultSet rs = null;
String mylog=id.getText().toString();
String mypass=pass.getText().toString();
try{
Statement statement=connect.createStatement();
rs=statement.executeQuery("LOGIN '"+mylog+"', '"+mypass+"'");
}catch(Exception e){
e.printStackTrace();
}
if(mylog.equals("")||mypass.equals("")){
Toast.makeText(getApplicationContext(), "empty fields", Toast.LENGTH_SHORT).show();
} else
try {
if(rs.next()){
Intent i=new Intent(getApplicationContext(),Act2.class);
startActivity(i);
}
else if(rs.next()==false){
Toast.makeText(getApplicationContext(), "incorrect login", Toast.LENGTH_SHORT).show();
id.setText("");
pass.setText("");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if it is possible that same method save() be kept inside doInbackground() of asyntask...
making a fast refactorization (note that this as it stand it's really bad practice and coding, you MUST refactor this code to be more maintanable and to avoid duplication):
public class MyAsyncTask extends AsyncTask<> {
private Activity activity;
boolean result;
private String myLog;
private String myPass;
private Connection connect;
public MyAsyncTask(Activity activity, Connection connect) {
this.activity = activity;
this.connect = connect;
}
#Override
protected void onPreExecute() {
//show your progress dialog
}
#Override
protected Object doInBackground(Object[] objects) {
ResultSet rs = null;
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
initilize();
mylog=id.getText().toString();
mypass=pass.getText().toString();
}
});
try{
Statement statement=connect.createStatement();
rs=statement.executeQuery("LOGIN '"+mylog+"', '"+mypass+"'");
}catch(Exception e){
e.printStackTrace();
}
if(mylog.equals("")||mypass.equals("")){
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(activity.getApplicationContext(), "empty fields", Toast.LENGTH_SHORT).show();
}
});
} else
try {
if(rs.next()){
result = true;
}
else if(rs.next()==false){
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(activity.getApplicationContext(), "incorrect login", Toast.LENGTH_SHORT).show();
id.setText("");
pass.setText("");
}
});
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object o) {
//hide your progress dialog
if(result == Boolean.TRUE){
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Intent i=new Intent(activity.getApplicationContext(),Act2.class);
activity.startActivity(i);
}
});
}
}
}
then in your Activity you do this:
MyAsyncTask a = new MyAsyncTask(this, connect); //im guessing "connect" is your Connection object
a.execute();
As i said i made this fast refactoring for the code to work but best practice and good implementation is not in consideration here.
Maybe, you could use a timer, to check if your
login is ready. As long as it is not, you Show your progress Bar. If its ready, you can close the Bar and start a new activity or anything. timers run can run on u UI thread.
regards :)
I am creating an android application that uses async task to login and send data(HTTP Post Request. The application works fine when internet connection is good but when logging and it takes too long to post data due to slow connection the application force closes. i would like to display a toast "Error in Connection" when this happens. Please Help
Your application probably crashes, because you are trying to show Toast not in a UI Thread. That is you always should make any changes to UI by using Handler, or within onPostExecute() method, which also runs in UI Thread.
How to catch exceptions in doInBackground's thread and represent them in UI Thread is another question, I can suggest you this solution:
private class LoginTask extends
AsyncTask<Void, Integer, JSONArray[]> {
private static final int NETWORK_NO_ERROR = -1;
private static final int NETWORK_HOST_UNREACHABLE = 1;
private static final int NETWORK_NO_ACCESS_TO_INTERNET = 2;
private static final int NETWORK_TIME_OUT = 3;
// You can continue this list...
Integer serverError = NETWORK_NO_ERROR;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.show(); // Don't forget to create it before
}
#Override
protected JSONArray[] doInBackground(Void... v) {
JSONArray[] result = null;
try {
result = NetworkManager.login(/* All params you need */);
} catch (JSONException e) {
return null;
} catch (ConnectException e) {
serverError = NETWORK_NO_ACCESS_TO_INTERNET;
return null;
} catch (UnknownHostException e) {
serverError = NETWORK_HOST_UNREACHABLE;
return null;
} catch (SocketTimeoutException e) {
serverError = NETWORK_TIME_OUT;
return null;
} catch (URISyntaxException e) {
// ..
return null;
} catch (ClientProtocolException e) {
// ..
return null;
} catch (Exception e) {
// ..
return null;
}
return result;
}
#Override
protected void onPostExecute(JSONArray[] result) {
progressDialog.dismiss();
if (result != null) {
processAndShowResult(result);
} else {
switch (serverError) {
case NETWORK_NO_ERROR:
Toast.makeText(YourActivity.this, "Probably, invalid response from server", Toast.LENGTH_LONG).show();
break;
case NETWORK_NO_ACCESS_TO_INTERNET:
// You can customize error message (or behavior) for different type of error
case NETWORK_TIME_OUT:
case NETWORK_HOST_UNREACHABLE:
Toast.makeText(YourActivity.this, "Error in Connection", Toast.LENGTH_LONG).show();
break;
}
}
}
}
By this means, you can flexibly control network errors and undertake appropriate actions, according to these errors.
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();
}
}