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方法中的參數接收。