【问题标题】:method gettext must be called from the ui thread currently inferred thread is worker [duplicate]方法 gettext 必须从当前推断线程是工作线程的 ui 线程调用 [重复]
【发布时间】:2017-10-25 12:52:26
【问题描述】:

两天前我才开始使用 Android Studio,而且我在 java 方面也没有太多经验。我制作了一个简单的登录应用程序来连接到 Sql 服务器作为数据库进行检查。我已经编写了从http://seotoolzz.com/android/android-login-app-with-mssql-server.php 引用的这段代码。但在以下行中显示错误:必须从 ui 线程调用方法 gettext。请帮忙,因为我对 android 应用程序开发非常陌生。非常感谢。

String usernam = username.getText().toString();

String passwordd = password.getText().toString();

 public class MainActivity extends AppCompatActivity

{

Button login;
EditText username,password;
ProgressBar progressBar;



Connection con;
String un,pass,db,ip;


@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    login = (Button) findViewById(R.id.button);
    username = (EditText) findViewById(R.id.editText);
    password = (EditText) findViewById(R.id.editText2);
    progressBar = (ProgressBar) findViewById(R.id.progressBar);



    ip = "1IP";
    db = "ADB";
    un = "your username for that database here";
    pass = "your password for that database here";
     login.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            CheckLogin checkLogin = new CheckLogin();
                checkLogin.execute("");
        }
    });

}

public class CheckLogin extends AsyncTask<String,String,String>
{
    String z = "";
    Boolean isSuccess = false;

    @Override
    protected void onPreExecute()
    {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onPostExecute(String r)
    {
        progressBar.setVisibility(View.GONE);
        Toast.makeText(MainActivity.this, r, Toast.LENGTH_SHORT).show();
        if(isSuccess)
        {
            Toast.makeText(MainActivity.this , "Login Successfull" , Toast.LENGTH_LONG).show();
            //finish();
        }
    }
    @Override
    protected String doInBackground(String... params)
    {
        String usernam = username.getText().toString();
        String passwordd = password.getText().toString();
        if(usernam.trim().equals("")|| passwordd.trim().equals(""))
            z = "Please enter Username and Password";
        else
        {
            try
            {
                con = connectionclass(un, pass, db, ip);       
                if (con == null)
                {
                    z = "Check Your Internet Access!";
                }
                else
                {
                                           String query = "select * from Login where UserName= '" + usernam.toString() + "' and Password = '"+ passwordd.toString() +"'  ";
                    Statement stmt = con.createStatement();
                    ResultSet rs = stmt.executeQuery(query);
                    if(rs.next())
                    {
                        z = "Login successful";
                        isSuccess=true;
                        con.close();
                    }
                    else
                    {
                        z = "Invalid Credentials!";
                        isSuccess = false;
                    }
                }
            }
            catch (Exception ex)
            {
                isSuccess = false;
                z = ex.getMessage();
            }
        }
        return z;
    }
}


@SuppressLint("NewApi")
public Connection connectionclass(String user, String password, String database, String server)
{
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
    Connection connection = null;
    String ConnectionURL = null;
    try
    {
        Class.forName("net.sourceforge.jtds.jdbc.Driver");
        ConnectionURL = "jdbc:jtds:sqlserver://" + server + database + ";user=" + user+ ";password=" + password + ";";
        connection = DriverManager.getConnection(ConnectionURL);
    }
    catch (SQLException se)
    {
        Log.e("error here 1 : ", se.getMessage());
    }
    catch (ClassNotFoundException e)
    {
        Log.e("error here 2 : ", e.getMessage());
    }
    catch (Exception e)
    {
        Log.e("error here 3 : ", e.getMessage());
    }
    return connection;
}

}

【问题讨论】:

  • 您好,请看这里,我认为 aysnc 任务无法访问文本框,但您可以将值传入。stackoverflow.com/questions/32324769/…
  • 遇到错误或异常时首先要做的是搜索现有答案。当您不理解异常消息中的某些单词时(并且考虑到您是 Java 新手——您正处于这种情况),您应该首先了解这些单词的含义,然后再阅读该消息。一旦你明白了哪里出了问题,解决问题就很容易了。

标签: java android sql-server


【解决方案1】:

您遇到的问题是由于访问外部类中的当前视图元素(编辑:或者更确切地说是在另一个非 UI 线程中)。

一种解决方法是使用 Activity.runOnUIThread(Runnable),如下所示:

String usernam, passwordd;
getActivity().runOnUIThread(new Runnable(){
    usernam = username.getText().toString();
    passwordd = password.getText().toString();
}

您还可以在调用时将字符串作为输入传递给 AsyncTask:

@Override
public void onClick(View v)
{
    CheckLogin checkLogin = new CheckLogin();
    checkLogin.execute(usernam.getText(),passwordd.getText());
}

并在 AsyncTask.doInBackground 中访问它:

@Override
protected String doInBackground(String... params)
{
    usernam = params[0];
    passwordd = params[1];
    ....
}

希望这有帮助。

【讨论】:

  • 我这样做了,但我应该在哪里添加这个字符串用户名,密码; getActivity().runOnUIThread
  • 访问用户名和密码字段之前。
【解决方案2】:

Asyntask 是一个单独的线程,无法访问 UI 线程元素。而是将值存储为全局成员变量并访问它们。

 String usernam,password;

然后在您的 onclickListener 中将值存储给它们。

login.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            usernam=username.getText().toString();
            password=password.getText().toString();
            CheckLogin checkLogin = new CheckLogin();
            checkLogin.execute("");
        }
    });

【讨论】:

    猜你喜欢
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多