I have a simple android application to access a web service. I want to show a dialog "Loading . . ." until results are loaded and dismissed after loading the results. I have used this code but this doesn't show the loading message:
public class LoadingActivity extends Activity {
private static final String SOAP_ACTION = "http://ws.eretailer.com/";
private static final String METHOD_NAME = "dataSender";
private static final String NAMESPACE = "http://ws.eretailer.com/dataSender/";
private static final String URL = "http://175.157.128.207:8085/Eretailer/services/EretailerService?wsdl";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ProgressDialog pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Loading. . .");
pd.show();
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
pd.show();
HttpTransportSE ht = new HttpTransportSE(URL);
try {
ht.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
SoapPrimitive s = response;
pd.dismiss();
String str = s.toString();
String arr1[] = str.split(" ");
TextView tv = new TextView(this);
for(int i = 0; i<arr1.length;i++){
tv.append("order ID :"+arr1[i]+"\n");
}
setContentView(tv);
} catch (Exception e) {
e.printStackTrace();
}
}
}
How can I correct this problem ?
Hi try as following code
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
pd.show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... urls) {
String response = "";
HttpTransportSE ht = new HttpTransportSE(URL);
try {
ht.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
SoapPrimitive s = response;
pd.dismiss();
String str = s.toString();
String arr1[] = str.split(" ");
TextView tv = new TextView(this);
for(int i = 0; i<arr1.length;i++){
tv.append("order ID :"+arr1[i]+"\n");
}
setContentView(tv);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
#Override
protected void onPostExecute(String result) {
pd.dismiss();
}
}
Resource : http://www.vogella.com/articles/AndroidPerformance/article.html
Better to use Android-AsyncTask for your Web Request. And start ProgressDialog in onPreExecute() of AsyncTask and close it in onPostExecute()(Update your UI here for result from Web response). Also put Web-Request code in doInBackGround() of AsyncTask..
For Example look at Android AsyncTask Example.
This will never block your Main-UI Thread. And better performance for User Experience.
first comment pd.dismiss() first and check if its loading is coming then use pd.dismiss() after downloading complete.
Related
I am using this asynctask Class to update two different tables on Sql Server so far this code works fine i'm interested in more better and sufficient code structure of this class specially in doinbackground() Is it okay to call multiple webservices methods in a single thread? can any one suggest me?
private class Update extends AsyncTask<Void, Void, Integer> {
private final int FAILED_INVALID_RESPONSE = 0;
private final int SUCCESS_GET_DATA = 1;
ProgressDialog progress;
private String _phoneno;
private String _ticket;
UpdateTicket(String phoneno,String ticket){
_phoneno=phoneno;
_ticket=ticket;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progress = ProgressDialog.show(XYZ.this, "",
"In Progress...", false);
}
#Override
protected Integer doInBackground(Void... params) {
method1(_phoneno);
return method2(_phoneno,_ticket);
}
#Override
protected void onPostExecute(Integer result) {
progress.dismiss();
switch (result) {
case FAILED_INVALID_RESPONSE:
Toast.makeText(XYZ.this,"Please Check your Internet Connection.",Toast.LENGTH_SHORT).show();
break;
case SUCCESS_GET_DATA:
Toast.makeText(XYZ.this, "Success!", Toast.LENGTH_SHORT).show();
break;
}
}
int method1(String phoneno,String tickets)
{
final String methodname = "firstmethod";
final String NAMESPACE ="http://tempuri.org/";
final String URL="www.sampleurl.com";
final String SOAP_ACTION="http://tempuri.org/firstmethod";
int success=0;
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
SoapObject request = new SoapObject(NAMESPACE, methodname);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
request.addProperty("phoneno", phoneno);
request.addProperty("tickets", tickets);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try{
androidHttpTransport.call(SOAP_ACTION,envelope);
SoapObject response = (SoapObject) envelope.bodyIn;
if(response!=null){
success=1;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return success;
}
int method2(String Phone) {
final String methodname = "secondmethod";
final String NAMESPACE ="http://tempuri.org/";
final String URL="www.sampleurl.com";
final String SOAP_ACTION="http://tempuri.org/secondmethod";
int success=0;
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
SoapObject request = new SoapObject(NAMESPACE, methodname);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
request.addProperty("phoneno", phoneno);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try{
androidHttpTransport.call(SOAP_ACTION,envelope);
SoapObject response = (SoapObject) envelope.bodyIn;
if(response!=null){
success=1;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return success;
}
}
AsyncTask should only be used for tasks/operations that take quite few seconds.
AsyncTasks are executed serially on a single background thread (from API 11). So long running worker can block others.
Check some other gotchas.
Take a look at HeandlerThread.
Tried using Async but got can't handler even there is no toast in it,
also tried call calling method runUIThread but no luck ,
Async method works but it also gets run time exception
when i use Async method data gets on the Textview too late (5-10 mins) , but when i use it in debuggers it gets instantly ,
below webservice is test using wizdl application and response is instant
i'm confused please help
private final String NAMESPACE = "http://????????.com/EventGetter/";
private final String URL = "http://?????????.com/EventGetter.asmx";
private final String SOAP_ACTION = "http://????????.com/EventGetter/GetTimeTable";
private final String METHOD_NAME = "GetTimeTable";
private class TPaccessData extends AsyncTask<String, Void, Void>{
#Override
protected Void doInBackground(String... params) {
GetData();
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(LogStr, "onPostExecute");
}
#Override
protected void onPreExecute() {
GetData();
Log.i(LogStr, "onPreExecute");
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i(LogStr, "onProgressUpdate");
}
}
public void GetData(){
//Create request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//set properties aka param
request.addProperty("stream","where ttBatch = 'F.Y.J.C'");
//Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
//Set output SOAP object
envelope.setOutputSoapObject(request);
//Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.debug = true;
//Invole web service
androidHttpTransport.call(SOAP_ACTION, envelope);
//Get the response
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
//Assign it to Text static variable
text.setText(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
also tried calling get data in oncreate method
NotifyList.this.runOnUiThread(new Runnable() {
#Override
public void run() {
GetData();
// TPaccessData task = new TPaccessData();
// task.execute();
}
});
Remove youe GetData() method from onPreExecute()
and call this line inside onPost
text.setText(response.toString());
I have this code to call a donNet web servise on localhost. The web service take 5 values and return a string.. I took this error: Error HTTP request failed, HTTP status 400.. What is the problem here?
public class MainActivity extends Activity {
private final String NAMESPACE = "http://tempuri.org/";
private final String URL = "http://10.0.2.2:6371/Service1.asmx";
int IDocID;
String SName,SDate,STime,SReason;
TextView txt;
private PropertyInfo AppDoctor,AppDate,AppTime,AppName,AppReason;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sent=(Button)findViewById(R.id.button1);
txt=(TextView)findViewById(R.id.textView6);
sent.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
EditText DocID=(EditText)findViewById(R.id.editTextDoc);
IDocID = Integer.parseInt(DocID.getText().toString());
EditText Date= (EditText)findViewById(R.id.editTextDate);
SDate = Date.getText().toString();
EditText Time=(EditText)findViewById(R.id.editTextTime);
STime = Time.getText().toString();
EditText Name=(EditText)findViewById(R.id.editTextName);
SName = Name.getText().toString();
EditText Reason=(EditText)findViewById(R.id.editTextReason);
SReason = Reason.getText().toString();
new InsertTask().execute();
}
});
}
private String doInsert(String SName,String SDate,String STime,String SReason, int IDocID ) {
String result="";
final String SOAP_ACTION = "http://tempuri.org/InsertAppointment";
final String METHOD_NAME = "InsertAppointment";
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("AppDoctor",IDocID);
request.addProperty("AppDate",SDate);
request.addProperty("AppTime",STime);
request.addProperty("AppName",SName);
request.addProperty("AppReason",SReason);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
System.out.println(request);
System.out.println(envelope.toString());
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
Log.i("myApp", response.toString());
/
if(response != null)
{
String resp= response.toString();
result = resp;
txt.setText(resp);
}
}catch(SocketException ex)
{
Log.e("Error : " , "Error on soapPrimitiveData() " + ex.getMessage());
ex.printStackTrace();
txt.setText(ex.toString());
}
catch (Exception e) {
Log.e("Error : " , "Error on soapPrimitiveData() " + e.getMessage());
e.printStackTrace();
}
return result;
}
private class InsertTask extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
protected void onPreExecute() {
this.dialog.setMessage("Logging in...");
this.dialog.show();
}
protected Void doInBackground(final Void... unused) {
String auth=doInsert( SName, SDate, STime, SReason, IDocID);
System.out.println(auth);
return null;// don't interact with the ui!
}
protected void onPostExecute(Void result) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
Try to add "" to your SOAP_ACTION:
final String SOAP_ACTION = "\"http://tempuri.org/InsertAppointment\"";
I'm implementing an AsyncTask, that calls a WCF service methods in the doInBackground method.
the WCF method name is a parameter for the doInBackground method.
I want the progress dialog to show only for specific methods name sent to doInBackground.
My porgressdialog setting are set in onPreExecute methods.
Any way to make progressdialog appear for a specific doInBackground parameter (wcf method name)
public class WCFHelper extends AsyncTask<Object, Void, String[]>{
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://url";
final ProgressDialog pd;
public Context ctx;
public WCFHelper(Context _ctx)
{ this.ctx = _ctx;
pd = new ProgressDialog(_ctx);
}
#Override
protected void onPreExecute() {
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("login...");
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
}
#Override
protected String[] doInBackground(Object... params) {
String WCFmethod = (String)params[0];
Map<String,Object> parameterArgs = (Map<String,Object>)params[1];
Boolean isArr = (Boolean)params[2];
String [] Fail = {"Fail"};
String SOAP_ACTION = "http://tempuri.org/IService1/"+WCFmethod;
String METHOD_NAME = WCFmethod;
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
for(Map.Entry<String,Object> entry: parameterArgs.entrySet())
request.addProperty(entry.getKey().toString(), entry.getValue().toString());
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
if(!isArr)
{
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
String[] toReturn = new String[1];
toReturn[0] = result.toString();
return toReturn;
}
else{
envelope.implicitTypes = true ;
SoapObject listDataSet = (SoapObject) envelope.bodyIn;
int numOfStrings = ((SoapObject)listDataSet.getProperty(0)).getPropertyCount();
String[] toReturn = new String[numOfStrings];
for ( int i = 0 ; i <numOfStrings; i++) {
toReturn[i] = ((SoapObject)listDataSet.getProperty(0)).getProperty(i).toString();
}
return toReturn;
}
}
catch (Exception e) {
return Fail;
}
}
protected void onPostExecute(String res) {
// TODO: check this.exception
// TODO: do something with the feed
if(this.pd.isShowing())
pd.dismiss();
}
As you can see one of the params for doInBackground is WCF method name.
I want the progressdialog to show only to specific WCF methods (received as parameter)
Send parameters also during instantiating the WCHelper object.
Keep a variable in the WCFHelper class.
public class WCFHelper extends AsyncTask<Object, Void, String[]>{
int val;
public WCHelper(int param) //constructor
{
super();
val = param; //now you can use this val in onPreExecute
}
...
}
Send the same parameter you wanted to send to onPreExecute(). For example,
WCHelper task = new WCHelper(param); // this sends value to constructor
task.execute(param); //this sends value to doInBackground
You can create your own custom constructor of the AsyncTask to transfer necessary parameter for handling the progress dialog.
private class MyTask extends AsyncTask<Void, Void, Void> {
public MyTask(boolean showProgress){
....
}
....
}
I'm coding an app that primarily uses data gotten from a web service, and I want to use AsyncTask to run the SOAP calls in the background... I'm fairly new to Android(being an iOS programmer), so I'm a bit new at this...
Now, I have a login screen, where I take a user-provided login and check it against information on a server...
So in my login activity:
loginBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
//Run the connection to authenticate the user
AuthenticateConnection mAuth = new AuthenticateConnection();
mAuth.mNumber = number;
mAuth.mPassword = pass;
mAuth.connection();
}
}
and my soap class is this:
public class AuthenticateConnection
{
private static final String SOAP_ACTION = "http://tempuri.org/Authenticate";
private static final String METHOD_NAME = "Authenticate";
private static final String NAMESPACE = "http://tempuri.org/";
private String URL;
public Boolean userOK;
public String mNumber;
public String mPassword;
public AuthenticateConnection()
{
}
public void connection()
{
Singleton service = Singleton.getInstance();
String firstURL = service.getURL();
URL = firstURL + "Parent.svc";
System.out.println("Connection to: " + URL);
//Initialize soap request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//Add parameters
request.addProperty("login", mNumber);
request.addProperty("password", mPassword);
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.implicitTypes=true;
envelope.setAddAdornments(false);
//Prepare request
envelope.setOutputSoapObject(request);
//Needed to make the internet call
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//Allow for debugging - needed to output the request
androidHttpTransport.debug = true;
try
{
//this is the actual part that will call the web service
androidHttpTransport.call(SOAP_ACTION, envelope);
//Get the SoapResult from the envelope body.
//Object result = envelope.getResponse();
//Object result = envelope.bodyIn;
SoapObject sResult = (SoapObject)envelope.bodyIn;
String tempID = sResult.getProperty("AuthenticateResult").toString();
//Check if the user exists and has the correct password
if(tempID != "-1")
{
userOK = true;
//Store the values in the singleton class
service.parentID = sResult.getProperty("AuthenticateResult").toString();
service.parentToken = sResult.getProperty("token").toString();
}
//If -1 is returned, then either the number or the password is incorrect
else
{
userOK = false;
}
} catch(org.xmlpull.v1.XmlPullParserException ex2)
{
//System.out.println(androidHttpTransport.requestDump.toString());
} catch (Exception e)
{
e.printStackTrace();
System.out.println(androidHttpTransport.requestDump.toString());
}
}
}
So my question is, how would I do this with AsyncTask?
I've been looking at some tutorial on AsyncTask, but haven't really "gotten it" so far...
You can do:
private class ConnectionTask extends AsyncTask<String, Void, Void> {
private ProgressDialog dialog = new ProgressDialog(ACTIVITY_NAME.this);
protected void onPreExecute() {
dialog.setMessage("Connecting...");
dialog.show();
}
protected void doInBackground(String... args) {
AuthenticateConnection mAuth = new AuthenticateConnection();
mAuth.mNumber = args[0];
mAuth.mPassword = args[1];
mAuth.connection();
}
protected void onPostExecute(Void v) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
And then call it:
loginBtn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
//Run the connection to authenticate the user
new ConnectionTask().execute(number, pass);
}
}
Your connection method in AuthenticateConnection should return something to ensure the user has been authenticated. Then you can use that value in the onPostExecute, something like this:
protected void onPostExecute(Integer res) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (res.intValue() == OK) {
/* Maybe start a new Activity ...*/
} else {
/* Maybe show a Toast with an error message ...*/
}
}
In this case the signature of the asynctask will change:
private class ConnectionTask extends AsyncTask<String, Void, Integer>
and the doInBackground should return an Integer.
Hope it helps.