【问题标题】:java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() WHY?java.lang.RuntimeException: Can't create handler inside the thread that has not called Looper.prepare() 为什么?
【发布时间】:2013-12-27 22:43:10
【问题描述】:

当我运行第一个活动时..没有错误 但是当我尝试运行第二个活动 ERROR "java.lang.RuntimeException: Can't create handler inside the thread that has not called Looper.prepare()"

没有活套问题的活动

package com.example.androidnotizer;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;


public class LoginActivity extends Activity {

public static final String URL="jdbc:mysql://10.0.2.2/notizer";
public static final String USER="root";
public static final String PASSWORD="apple";
public static final String Driver_Class="com.mysql.jdbc.Driver";
public static final int RED=-65536;

Handler handler = new Handler();
Thread background;
String uid,pass;
int count=0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    TextView tv = (TextView)findViewById(R.id.textView4);
    tv.setText("");
    Button login = (Button) findViewById(R.id.button1);
    login.setOnClickListener(new OnClickListener(){
        @Override
        public void onClick(View arg0) {
            EditText et1 = (EditText)findViewById(R.id.editText1);
            EditText et2 = (EditText)findViewById(R.id.editText2);
            uid=et1.getText().toString();
            pass=et2.getText().toString();
            TextView tv = (TextView)findViewById(R.id.textView4);
            tv.setText("");
            count=0;
            doLogin();
        }
    });

}

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_signup:
            Intent i = new Intent(LoginActivity.this,SignUpActivity.class);
            startActivity(i);
    }
    return true;
}

public void doLogin(){
    background = new Thread(new Runnable(){
        @Override
        public void run(){
            try{
                Class.forName(Driver_Class);
                Connection con = DriverManager.getConnection(URL, USER, PASSWORD);
                Statement st = con.createStatement();
                ResultSet rs =st.executeQuery("select * from login where user_id='"+ uid +"' and password='"+ pass +"'");
                while(rs.next()){
                    count++;
                }
            }catch(Exception e){
                e.printStackTrace();
            }
            Runnable r=new Runnable() {
                   @Override
                   public void run() {
                       if(count==0){
                           Toast.makeText(getApplicationContext(), "Unsuccessful Login", Toast.LENGTH_SHORT).show();
                            TextView tv = (TextView)findViewById(R.id.textView4);
                            tv.setText("Wrong user_id or password");
                            tv.setTextColor(RED);  
                       }
                       else{
                           Intent i = new Intent(LoginActivity.this,NoticeActivity.class);
                           startActivity(i);
                       }
                   }
                };
                handler.post(r);
            }
        }
    );
    background.start();
}

}

有活套问题的活动

package com.example.androidnotizer;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.SparseBooleanArray;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class StudentSignUpActivity extends Activity implements OnClickListener {

public static final String URL="jdbc:mysql://10.0.2.2/notizer";
public static final String USER="root";
public static final String PASSWORD="apple";
public static final String Driver_Class="com.mysql.jdbc.Driver";

Handler handler = new Handler();
Thread background;

Button button,combi;
ListView listView;
ArrayAdapter<String> adapter;
String fname,lname,mname,gender,mobile,designation,passPapers,roll,department,year;
int count=0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_student_sign_up);
    Intent intent =getIntent();
    fname = intent.getStringExtra("fname");
    mname = intent.getStringExtra("mname");
    lname = intent.getStringExtra("lname");
    gender = intent.getStringExtra("gender");
    mobile = intent.getStringExtra("mobile");
    designation = intent.getStringExtra("designation");
    roll = intent.getStringExtra("roll");
    department = intent.getStringExtra("department");
    year = intent.getStringExtra("year");
    findViewById();
    String[] sports = getResources().getStringArray(R.array.papers_array);
    adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_multiple_choice, sports);
    listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    listView.setAdapter(adapter);
    button.setOnClickListener(this);
}

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

private void findViewById() {
    listView = (ListView) findViewById(R.id.dept_listView1);
    button = (Button) findViewById(R.id.done);
}

@Override
public void onClick(View arg0) {
    SparseBooleanArray checked = listView.getCheckedItemPositions();
    passPapers="";
    for (int i = 0; i < checked.size(); i++) {
        int position = checked.keyAt(i);
        if (checked.valueAt(i))
            if((i+1) < checked.size()){
                passPapers=passPapers+String.valueOf(adapter.getItem(position))+",";
            }
            else{
                passPapers=passPapers+String.valueOf(adapter.getItem(position));
            }

    }
    doSignUp();
}

public void doSignUp(){
    Toast.makeText(getApplicationContext(),"Inside doSignUp()",Toast.LENGTH_LONG).show();
    background = new Thread(new Runnable(){
        @Override
        public void run(){
            try{
                Toast.makeText(getApplicationContext(),"Inside try",Toast.LENGTH_LONG).show();
                Class.forName(Driver_Class);
                Connection con = DriverManager.getConnection(URL, USER, PASSWORD);
                Statement st = con.createStatement();
                //st.executeUpdate("insert into student(roll_no,fname,mname,lname,gender,mobile_no,department,year,pass_papers,desigantion) values('"+ roll +"','"+ fname +"','"+ mname +"','"+ lname +"','"+ gender +"','"+ mobile +"','"+ department +"','"+ year +"','"+ passPapers +"','"+ designation +"')");
                st.executeUpdate("insert into login(user_id,password) values('"+ roll +"','"+ roll +"')");
                count=1;
            }catch(Exception e){
                count=0;
                e.printStackTrace();
                Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
            }
            Runnable r=new Runnable() {
                   @Override
                   public void run() {
                       if(count==1){
                           Toast.makeText(getApplicationContext(), "Successful Sign Up\nYour user_id : " + roll + "\nand password : " + roll, Toast.LENGTH_LONG).show();
                           Intent i = new Intent(StudentSignUpActivity.this,NoticeActivity.class);
                           startActivity(i);
                       }
                       else{
                           Toast.makeText(getApplicationContext(), "Unsuccessful Sign Up\nTry Again", Toast.LENGTH_LONG).show();
                           Intent i = new Intent(StudentSignUpActivity.this,SignUpActivity.class);
                           startActivity(i);
                       }
                   }
                };
                handler.post(r);
            }
        }
    );
    background.start();
}

}

LogCat

12-10 06:49:48.823: E/AndroidRuntime(5021): FATAL EXCEPTION: Thread-344
12-10 06:49:48.823: E/AndroidRuntime(5021): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
12-10 06:49:48.823: E/AndroidRuntime(5021):     at android.os.Handler.<init>(Handler.java:197)
12-10 06:49:48.823: E/AndroidRuntime(5021):     at android.os.Handler.<init>(Handler.java:111)
12-10 06:49:48.823: E/AndroidRuntime(5021):     at android.widget.Toast$TN.<init>(Toast.java:324)
12-10 06:49:48.823: E/AndroidRuntime(5021):     at android.widget.Toast.<init>(Toast.java:91)
12-10 06:49:48.823: E/AndroidRuntime(5021):     at android.widget.Toast.makeText(Toast.java:238)
12-10 06:49:48.823: E/AndroidRuntime(5021):     at com.example.androidnotizer.StudentSignUpActivity$1.run(StudentSignUpActivity.java:104)
12-10 06:49:48.823: E/AndroidRuntime(5021):     at java.lang.Thread.run(Thread.java:841)

【问题讨论】:

  • 这个问题你解决了吗?
  • 是的,我已经...只是多加了两行
  • 如果你在这里分享你的努力会很好
  • 在 try 块之前添加 Looper.prepare(); 和之后 handler.post(r);添加 Looper.loop();
  • 我无法理解 ypu 是如何解决问题的。你能分享你的代码吗?

标签: java android multithreading


【解决方案1】:

您必须从 UI 线程本身运行 toast 消息。使用这个:

LoginActivity.this.runOnUiThread(new Runnable() {
        public void run() {

         if(count==1){
                       Toast.makeText(getApplicationContext(), "Successful Sign Up\nYour user_id : " + roll + "\nand password : " + roll, Toast.LENGTH_LONG).show();
                       Intent i = new Intent(StudentSignUpActivity.this,NoticeActivity.class);
                       startActivity(i);
                   }
         else{
                       Toast.makeText(getApplicationContext(), "Unsuccessful Sign Up\nTry Again", Toast.LENGTH_LONG).show();
                       Intent i = new Intent(StudentSignUpActivity.this,SignUpActivity.class);
                       startActivity(i);
                   }
                        });

将此放入您创建的线程中。

【讨论】:

    【解决方案2】:
    public void doSignUp(){
            background = new Thread(new Runnable() {
                @Override
                public void run() {
                    String error = "-1";
                    try {
                        Class.forName(Driver_Class);
                        Connection con = DriverManager.getConnection(URL, USER, PASSWORD);
                        Statement st = con.createStatement();
                        st.executeUpdate("insert into login(user_id,password) values('"+ roll +"','"+ roll +"')");
                        count=1;
                    } catch(Exception e) {
                        count=0;
                        e.printStackTrace();
                        error = e.toString();
                    }
                    final String cause = error;
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if(count==1) {
                                Toast.makeText(getApplicationContext(), "Successful Sign Up\nYour user_id : " + roll + "\nand password : " + roll, Toast.LENGTH_LONG).show();
                                Intent i = new Intent(StudentSignUpActivity.this,NoticeActivity.class);
                                startActivity(i);
                            } else {
                                Toast.makeText(getApplicationContext(), "Unsuccessful Sign Up\nTry Again (Cause : " + cause + ")", Toast.LENGTH_LONG).show();
                                Intent i = new Intent(StudentSignUpActivity.this,SignUpActivity.class);
                                startActivity(i);
                            }
                        }
                    });
                }
            });
            background.start();
        }
    

    试试这个示例

    【讨论】:

    • 第二个活动的意思是?
    • 是的。你在单独的线程(doSignUp)中制作吐司,但不允许在单独的线程中修改 UI。
    猜你喜欢
    • 1970-01-01
    • 2019-08-28
    • 2011-10-07
    • 2023-03-18
    • 2013-05-04
    • 2021-09-28
    • 2022-11-17
    • 2018-11-09
    • 2021-08-21
    相关资源
    最近更新 更多