0

所以我正在构建这个 android 应用程序,并且我正在处理当用户输入错误的用户名或密码时要显示的错误消息。错误消息现在偶尔显示。我得到一个名为的异常

android.view.viewroot$callfromwrongthreadexception

当我仅研究时,作者基本上说,当您使用 AsyncTask 时,在 doinBackground 方法中设置文本不是一个好主意。由于在 onPostExecute 中设置测试会在任何时候显示登录成功与否的方法,所以我想出的部分解决方案是这样的。

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
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.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class Login extends Activity {
    static EditText alog;
    static EditText apass;
    JSONParser jsnParser = new JSONParser();
    public static String url_login="...";
    private static final String TAG_SUCCESS = "operation";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent it =getIntent();
        setContentView(R.layout.activity_login);
         alog=(EditText)findViewById(R.id.loginuser);
         apass=(EditText)findViewById(R.id.loginpass);

          Button btnLogin = (Button)findViewById(R.id.loggin);
          Button btnRegister =(Button)findViewById(R.id.register2);

          btnRegister.setOnClickListener(new View.OnClickListener() {


                public void onClick(View view) {

                    Intent i=new Intent(Login.this, Registration.class);
                    startActivity(i);
                }
            });

          btnLogin.setOnClickListener(new View.OnClickListener() {


            public void onClick(View view) {

                new LoggerIn().execute();
            }
        });


    }
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.login, menu);
        return true;
    }

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

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

            String logger=alog.getText().toString();
            String passer=apass.getText().toString();



        List <NameValuePair> prm=new ArrayList<NameValuePair>();
        prm.add(new BasicNameValuePair("username", logger));
        prm.add(new BasicNameValuePair("password", passer));

        JSONObject jsn= jsnParser.makeHttpRequest(url_login, "POST", prm);


        Log.d("Create Response", jsn.toString());
        try {
            boolean success=jsn.getBoolean(TAG_SUCCESS);

            if (success == true) {
                // successfully created product
                Intent i = new Intent(getApplicationContext(), Home.class);

                startActivity(i);

                // closing this screen
                finish();
            } else {
                // failed to create product
                //onPostExecute
                //TextView txt=(TextView)findViewById(R.id.login_error);
                //txt.setText("The username or password you entered was wrong");
                displayError();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
        }

        protected void displayError() {
            // dismiss the dialog after getting all products

            // updating UI from Background Thread
            TextView txt=(TextView)findViewById(R.id.login_error);
            txt.setText("The username or password you entered was wrong");

        }
    }



}

但是,当我无法登录时,我必须重复失败 2 或 3 次才能出现消息。有没有合适的方法来做到这一点?

4

2 回答 2

2

问题似乎是您试图从AsyncTask. 如果您想更改 UI 线程(即显示 Toast、设置TextView等),请在onPostExecute()方法或使用中进行,您也可以使用runOnUiThreaddoInBackground.

请参阅上面的问题,该问题进一步解释了您遇到的错误以及如何更正:如何修复 android.os.NetworkOnMainThreadException?

请参阅此处如何从内部调用 UI 线程上的方法AsyncTaskAndroid:从 AsyncTask doInBackground 方法调用 UI 线程上的方法

希望这可以帮助。

于 2013-07-16T00:24:01.187 回答
0

您只能从 UI 线程更新 UI。从有权访问 UI 线程的方法执行 Asynctask 中的所有 UI 调用,即onPreExecute(),onProgressUpdate()onPostExecute().

于 2013-07-16T00:24:35.783 回答