Método getText () debe llamarse desde el subproceso UI (Android Studio)

Estoy tratando de crear un inicio de sesión para una aplicación. Sin embargo, tengo un problema.

Este es mi código:

package com.forgetmenot.loginregister; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity { EditText uname, password; Button submit; // Creating JSON Parser object JSONParser jParser = new JSONParser(); private static final String TAG = "Login"; JSONObject json; private static String url_login = "http://localhost:8080/ForgetMeNotApplication/Login"; //JSONArray incoming_msg = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewsById(); submit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // execute method invokes doInBackground() where we open a Http URL connection using the given Servlet URL //and get output response from InputStream and return it. new Login().execute(); } }); } private void findViewsById() { uname = (EditText) findViewById(R.id.txtUser); password = (EditText) findViewById(R.id.txtPass); submit = (Button) findViewById(R.id.login); } private class Login extends AsyncTask{ @Override protected String doInBackground(String... args) { // Getting username and password from user input String username = uname.getText().toString(); String pass = password.getText().toString(); List params = new ArrayList(); params.add(new BasicNameValuePair("u",username)); params.add(new BasicNameValuePair("p",pass)); json = jParser.makeHttpRequest(url_login, "GET", params); String s=null; try { s= json.getString("info"); Log.d("Msg", json.getString("info")); if(s.equals("success")){ Intent login = new Intent(getApplicationContext(), home.class); login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(login); finish(); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } 

El estudio de Android dice que se debe llamar al método getText() desde el subproceso UI en las instrucciones: uname.getText().toString(); y password.getText().toString(); ¿¿Soluciones posibles??

Intente pasar Sus valores a Login AsyncTask mediante el Login AsyncTask execute(param1, param1, ..., paramN) :

 submit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { String username = uname.getText().toString(); String pass = password.getText().toString(); new Login().execute(username, pass); } }); } private void findViewsById() { uname = (EditText) findViewById(R.id.txtUser); password = (EditText) findViewById(R.id.txtPass); submit = (Button) findViewById(R.id.login); } private class Login extends AsyncTask{ @Override protected String doInBackground(String... args) { // Getting username and password from user input String username = args[0]; String pass = args[1]; 

hacer username y pass variable de clase de login y anular onPreExcecute() y hacer esto:

  @Override protected void onPreExecute() { username = uname.getText().toString(); pass = password.getText().toString(); } 

Está accediendo al hilo de la interfaz de usuario de un hilo de fondo aquí:

 String username = uname.getText().toString(); String pass = password.getText().toString(); 

Lo que quiere hacer es pasar las cadenas de nombre de usuario / contraseña a su constructor de tareas en segundo plano o puede pasarlas directamente al método de ejecución. Prefiero definirlos en el constructor si van a ser necesarios (como los tuyos).

Defina su LoginTask como

 String uname; String password; public Login(String username, String password({ this.uname = username; this.password = password; } 

Luego, en doInBackground () usa los miembros en su lugar.

 List params = new ArrayList(); params.add(new BasicNameValuePair("u",this.username)); params.add(new BasicNameValuePair("p",this.pass)); json = jParser.makeHttpRequest(url_login, "GET", params); 

Editar – entonces su nueva llamada a Login (). Execute () se vería más como esto

 new Login(uname.getText().toString(), password.getText().toString()).execute(); 

A menos que haya cambiado algo que yo no sepa, eso no debería ser un problema. Los elementos de la IU no se pueden actualizar desde el fondo, pero acceder a sus captadores nunca ha sido un problema.

De todos modos, puedes evitar esto agregando un constructor a tu AsyncTask que tomaría las dos AsyncTask y luego las enviaría al crear tu tarea.

 private class Login extends AsyncTask{ // member variables of the task class String uName, pwd public Login(String userName, String password) { uName = userName; pwd = password; } @Override protected String doInBackground(String... args) {...} 

y pasarlos en su onClick()

  @Override public void onClick(View arg0) { // execute method invokes doInBackground() where we open a Http URL connection using the given Servlet URL //and get output response from InputStream and return it. // pass them here new Login(uname.getText().toString(), password.getText().toString()).execute(); } 

La excepción se produce porque doInBackground() se invoca desde un hilo de fondo. Agregaría dos parámetros de cadena al constructor de su clase de Login de Login .

Me gustaría aconsejarle que obtenga más conocimiento sobre AsyncTasks y Threading en Android. Por ejemplo, hay una página en los documentos oficiales: http://developer.android.com/guide/components/processes-and-threads.html .

También puede echar un vistazo a este curso: https://www.udacity.com/course/developing-android-apps–ud853 . Puede aprender muchos conceptos básicos del marco Android.