2015-08-14 5 views
3

Я пытаюсь создать логин для приложения. Однако у меня есть проблема.Метод getText() должен быть вызван из потока пользовательского интерфейса (Android Studio)

Это мой код:

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<String, String, String>{ 

     @Override 
     protected String doInBackground(String... args) { 
      // Getting username and password from user input 

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

      List<NameValuePair> params = new ArrayList<NameValuePair>(); 
      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); 
    } 
} 

Android студия говорит, что метод getText() должен быть вызван из пользовательского интерфейса на тему istructions: uname.getText().toString(); и password.getText().toString(); Возможных решений ??

ответ

12

пытаются передать свои ценности в 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<String, String, String>{ 

     @Override 
     protected String doInBackground(String... args) { 
      // Getting username and password from user input 

      String username = args[0]; 
      String pass = args[1]; 
2

сделать переменную username и passlogin класс и переопределить onPreExcecute() и сделать это:

@Override 
    protected void onPreExecute() { 

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

    } 
0

Исключение брошено, поскольку doInBackground() вызывается из фонового потока. Я бы добавил два параметра String к конструктору вашего класса Login.

Я хотел бы посоветовать вам узнать больше о AsyncTasks и Threading на Android. Например, в официальных документах есть страница: http://developer.android.com/guide/components/processes-and-threads.html.

Вы также можете ознакомиться с этим курсом: https://www.udacity.com/course/developing-android-apps--ud853. Вы можете изучить множество основ Android-платформы.

1

Вы получаете доступ потока пользовательского интерфейса от фонового потока здесь:

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

То, что вы хотите сделать, это просто передать строки имя пользователя/пароль, чтобы фонового конструктора задачи или вы можете передать их непосредственно метод выполнения. Я предпочитаю их определять в конструкторе, если они потребуются (например, ваши).

Определите LoginTask как

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

Тогда в doInBackground() вы используете вместо членов.

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

Edit - так тогда ваш новый Логин() выполнить() вызов будет выглядеть как этот

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

Если что-то не изменилось, что я не в курсе, что не должно быть. проблема. Элементы пользовательского интерфейса не могут обновляться с фона, но доступ к их геттерам никогда не был проблемой.

В любом случае, вы можете обойти это, добавив конструктор к вашему AsyncTask, который возьмет два String s, а затем отправьте их при создании своей задачи.

private class Login extends AsyncTask<String, String, String>{ 

    // 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) {...} 

и передать их в 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(); 
} 
+0

На моем API 19 устройства, я обнаружил, что 'GetText() ', похоже, работает, но другие методы, такие как' getBitmap() 'TextureView', сбой. – VinceFior

+0

Я думаю, что 'getText' может быть доступным в рабочем потоке, это всего лишь идеальный намек, а не исключение во время выполнения – Ninja

Смежные вопросы

 Смежные вопросы