0

我是SOAP webservices和AsyncTask的新手,我正在开发一个使用SOAP webservices进行登录的应用程序。 我试图做所有的onCreate方法的工作,但我得到了android.os.NetworkOnMainThreadException。AsyncTask和SOAP webservices

所以我尝试使用AsyncTask, 但我无法在RetrieveFeedTask类中获得对emailText和passwordText的引用。

这里是我的代码:

public class MainActivity extends AppCompatActivity 
     implements NavigationView.OnNavigationItemSelectedListener { 


    private static String SOAP_ACTION = "intentionally hided"; 
    private static String NAMESPACE = "intentionally hided"; 
    private static String METHOD_NAME = "intentionally hided"; 
    private static String URL = "intentionally hided"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     final EditText emailText = (EditText) findViewById(R.id.emailText); 
     final EditText passwordText = (EditText) findViewById(R.id.passwordText); 
     Button loginButton = (Button) findViewById(R.id.button_login); 

     loginButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       new RetrieveFeedTask().execute(); 

      } 
     }); 
    } 

    class RetrieveFeedTask extends AsyncTask<String, String, String> { 



     protected String doInBackground(String... urls) { 


      SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

      request.addProperty("userName", emailText.getText().toString()); 
      request.addProperty("userPassword", passwordText.getText().toString()); 

      SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 

      envelope.setOutputSoapObject(request); 
      envelope.dotNet = true; 

      try { 
       HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 

       androidHttpTransport.call(SOAP_ACTION, envelope); 

       SoapObject result = (SoapObject) envelope.bodyIn; 
       if (result != null) { 
        Toast.makeText(getApplicationContext(), "Login Successful!", Toast.LENGTH_LONG).show(); 
       } else { 
        Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_LONG).show(); 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
+0

似乎有一篇文章在这里 - > http://www.helloandroid.com/tutorials/using-ksoap2 -android-and-parsing-output-data解释如何做到这一点。但是,如果可能的话,我会研究json和rest API,而不是SOAP Webservices。 –

回答

0

你可以使用这个(用的AsyncTask和onPreExecute onPostExecute,但没有NetworkOnMainThreadException):

class RetrieveFeedTask extends AsyncTask<String, String, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected String doInBackground(String... urls) { 

     String result = ""; 

     SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

     request.addProperty("userName", emailText.getText().toString()); 
     request.addProperty("userPassword", passwordText.getText().toString()); 

     SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 

     envelope.setOutputSoapObject(request); 
     envelope.dotNet = true; 

     try { 
      HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 

      androidHttpTransport.call(SOAP_ACTION, envelope); 

      SoapObject result = (SoapObject) envelope.bodyIn; 
      if (result != null) { 
       result = "Login Successful!"; 
      } else { 
       result = "Login Failed!"; 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return result; 
    } 

    @Override 
    protected String onPostExecute(String result) { 
     super.onPostExecute(result); 

     if (result.equals("Login Successful!")) { 
      Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show(); 
     } else { 
      Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_LONG).show(); 
     } 
    } 
} 
+0

谢谢,我还有一个解决方案之前,我也试过你的解决方案,它的工作就像魅力。 –

3

你可以的意见文本值传递到异步任务的构造,并通过内部基准访问它们。

class RetrieveFeedTask extends AsyncTask<String, String, String> { 

    private String emailText, passwordText; 

    RetrieveFeedTask(String emailText, String passwordText) { 
     this.emailText = emailText; 
     this.passwordText = passwordText; 
    } 

    protected String doInBackground(String... urls) { 
     ... 
    } 
} 

你会然后调用它像这样:

new RetrieveFeedTask(
     emailText.getText().toString(), 
     passwordText.getText().toString() 
).execute(); 

或者,你可以直接将参数传递给doInBackground()作为数组。

protected Void doInBackground(String... urls) { 
    String email = urls[0];  
    String password = urls[1]; 
    .... 
} 

然后调用它像这样:

String[] urls = { 
    emailText.getText().toString(), 
    passwordText.getText().toString() 
}; 

new RetrieveFeedTask().execute(urls); 
+0

感谢您的回复我做了同样的事情,但问题仍然在说“方法getText必须从UI线程调用”。 –

+0

对不起,我误解了你的问题。我已经更新了我的答案。您无法从非UI线程修改视图的状态。您得到该错误的原因是因为doInBackground()在非UI线程上运行。 – 345

+0

谢谢,解决了这个问题,但现在说它应该有一些从doInBackground方法返回的东西,而我没有什么可以返回的,你能帮助这方面吗? –

0

您通过emailText和passwordText直接进入的AsyncTask,你只需要进行一些小的改动:

首先在你的onClick监听器:

String email = emailText.getText()。toString();

String password = passwordText.getText()。toString();

new RetrieveFeedTask()。execute(email,password);

其次在你的AsyncTask doInBackground方法:

字符串email =网址[0];

String password = url [1];

几乎可以将任意值传递给AsyncTask的execute方法,这些方法作为doInBackground方法中的参数接收。