Java Can';t在未调用Looper.prepare()的线程内创建处理程序
我收到以下错误“无法在未调用Looper.prepare()的线程内创建处理程序” 你能告诉我怎么修吗Java Can';t在未调用Looper.prepare()的线程内创建处理程序,java,android,handler,Java,Android,Handler,我收到以下错误“无法在未调用Looper.prepare()的线程内创建处理程序” 你能告诉我怎么修吗 public class PaymentActivity extends BaseActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.payment); fin
public class PaymentActivity extends BaseActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.payment);
final Button buttonBank = (Button) findViewById(R.id.buttonBank);
buttonBank.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
progressDialog = ProgressDialog.show(PaymentActivity.this, "",
"Redirecting to payment gateway...", true, true);
new Thread() {
public void run() {
try {
startPayment("Bank");
} catch (Exception e) {
alertDialog.setMessage(e.getMessage());
handler.sendEmptyMessage(1);
progressDialog.cancel();
}
}
}.start();
}
});
起付方式:
private void startPayment(String id) {
Bundle b = getIntent().getExtras();
final Sail sail = b.getParcelable(Constant.SAIL);
final Intent bankIntent = new Intent(this, BankActivity.class);
try {
Reservation reservation = RestService.createReservation(
sail.getId(),
getSharedPreferences(Constant.PREF_NAME_CONTACT, 0));
bankIntent.putExtra(Constant.RESERVATION, reservation);
// <workingWithDB> Storing Reservation info in Database
DBAdapter db = new DBAdapter(this);
db.open();
@SuppressWarnings("unused")
long rowid;
rowid = db.insertRow(sail.getId(), sail.getFrom(),
sail.getTo(), sail.getShip(), sail.getDateFrom().getTime(),
sail.getPrice().toString(), reservation.getId().floatValue());
db.close();
// </workingWithDB>
String html = PaymentService.getRedirectHTML(id, reservation);
bankIntent.putExtra(Constant.BANK, html);
} catch (Exception e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alertDialog = builder.create();
alertDialog.setMessage(e.getMessage());
alertDialog.show();
}
startActivity(bankIntent);
}
private void startPayment(字符串id){
Bundle b=getIntent().getExtras();
最终帆=b.getParcelable(恒定帆);
最终意图bankIntent=新意图(此为BankActivity.class);
试一试{
Reservation Reservation=RestService.createReservation(
sail.getId(),
GetSharedReferences(常数.PREF_NAME_CONTACT,0));
bankIntent.putExtra(常量、保留、保留);
//在数据库中存储预订信息
DBAdapter db=新的DBAdapter(此);
db.open();
@抑制警告(“未使用”)
长罗非鱼;
rowid=db.insertRow(sail.getId(),sail.getFrom(),
sail.getTo(),sail.getShip(),sail.getDateFrom().getTime(),
sail.getPrice().toString(),reservation.getId().floatValue();
db.close();
//
字符串html=PaymentService.getRedirectHTML(id,预订);
bankIntent.putExtra(Constant.BANK,html);
}捕获(例外e){
AlertDialog.Builder=新建AlertDialog.Builder(此);
AlertDialog AlertDialog=builder.create();
alertDialog.setMessage(例如getMessage());
alertDialog.show();
}
星触觉(bankIntent);
}
我假设您在startPayment()方法中创建了一个处理程序。您不能这样做,因为处理程序只能在UI线程上创建。只需在活动类中创建它。而不是新建线程()
行,尝试
this.runOnUiThread(new Runnable() {
您应该知道,当您尝试修改UI时,只有
UiThread
线程可以修改UI
因此,如果您想在另一个线程中修改UI,请尝试使用以下方法:Activity.runOnUiThread(newrunnable)代码>
您的代码应该如下所示:
new Thread() {
public void run() {
YourActivity.this.runOnUiThread(new Runnable(){
@Override
public void run(){
try {
startPayment("Bank");//Edit,integrate this on the runOnUiThread
} catch (Exception e) {
alertDialog.setMessage(e.getMessage());
handler.sendEmptyMessage(1);
progressDialog.cancel();
}
});
}
}
}.start();
您不能更改线程中的任何UI,您可以使用runOnUIThread
或AsyncTask
了解有关此的更多详细信息我发现大多数线程处理都可以由以下异步任务代替:
public class TestStuff extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonBank = (Button) findViewById(R.id.button);
buttonBank.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new StartPaymentAsyncTask(TestStuff.this).execute((Void []) null);
}
});
}
private class StartPaymentAsyncTask extends AsyncTask<Void, Void, String> {
private ProgressDialog dialog;
private final Context context;
public StartPaymentAsyncTask(Context context) {
this.context = context;
}
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(context);
// setup your dialog here
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(context.getString(R.string.doing_db_work));
dialog.setCancelable(false);
dialog.show();
}
@Override
protected String doInBackground(Void... ignored) {
String returnMessage = null;
try {
startPayment("Bank");
} catch (Exception e) {
returnMessage = e.getMessage();
}
return returnMessage;
}
@Override
protected void onPostExecute(String message) {
dialog.dismiss();
if (message != null) {
// process the error (show alert etc)
Log.e("StartPaymentAsyncTask", String.format("I received an error: %s", message));
} else {
Log.i("StartPaymentAsyncTask", "No problems");
}
}
}
public void startPayment(String string) throws Exception {
SystemClock.sleep(2000); // pause for 2 seconds for dialog
Log.i("PaymentStuff", "I am pretending to do some work");
throw new Exception("Oh dear, database error");
}
}
公共类TestStuff扩展活动{
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button Button Bank=(按钮)findViewById(R.id.Button);
buttonBank.setOnClickListener(新视图.OnClickListener(){
公共void onClick(视图v){
新建StartPaymentAsyncTask(TestStuff.this).execute((Void[])null);
}
});
}
私有类StartPaymentAsyncTask扩展了AsyncTask{
私人对话;
私人最终语境;
公共StartPaymentAsyncTask(上下文){
this.context=上下文;
}
@凌驾
受保护的void onPreExecute(){
dialog=新建进度对话框(上下文);
//在此处设置对话框
setProgressStyle(ProgressDialog.STYLE_微调器);
setMessage(context.getString(R.string.doing_db_work));
对话框。可设置可取消(false);
dialog.show();
}
@凌驾
受保护的字符串doInBackground(无效…忽略){
字符串returnMessage=null;
试一试{
startPayment(“银行”);
}捕获(例外e){
returnMessage=e.getMessage();
}
返回消息;
}
@凌驾
受保护的void onPostExecute(字符串消息){
dialog.dismise();
如果(消息!=null){
//处理错误(显示警报等)
Log.e(“StartPaymentAsyncTask”,String.format(“我收到一个错误:%s”,消息));
}否则{
Log.i(“StartPaymentAsyncTask”,“没有问题”);
}
}
}
public void startPayment(字符串)引发异常{
SystemClock.sleep(2000);//暂停2秒以进行对话
Log.i(“PaymentStuff”,“我在假装做一些工作”);
抛出新异常(“哦,天哪,数据库错误”);
}
}
我将应用程序上下文传递给Async,以便它可以从中创建对话框
这样做的好处是您确切地知道哪些方法在UI中运行,哪些方法在单独的后台线程中运行。您的主UI线程没有延迟,并且将其分离为小型异步任务非常好
代码假定startPayment()方法对UI不做任何操作,如果做了,则将其移动到AsyncTask的onPostExecute中,以便在UI线程中完成该操作。Try
final Handler handlerTimer = new Handler(Looper.getMainLooper());
handlerTimer.postDelayed(new Runnable() {
public void run() {
......
}
}, time_interval});
请发布StartPaymentSyncTask()方法代码。我在“new StartPaymentSyncTask(this).execute((Void[])null)}”错误-构造函数PaymentActivity.StartPaymentSyncTask(new View.OnClickListener(){})是未定义的,这个
应该是YourActivity.this
。我已经更新了代码(我认为应该是PaymentActivity)断点onClick方法和异步任务的构造函数,以查看它们是否正常工作(或添加日志记录)。您是否为进度对话框添加了所有设置?我在上面为它添加了示例代码。我修改了代码,使之成为一个完全的工人阶级。如果您使用的是eclipse,您所需要做的就是向默认的android应用程序添加一个id为“button”的按钮,以使其正常工作。如果您注释掉最后抛出的异常,您将得到“no problems”消息您是尝试了整个类,还是只是插入了代码所需的位?修改后的代码应该显示一个微调器2秒钟(你看到了吗?),然后在日志中你应该看到startPayment()方法中的“我在假装做事情”,然后在日志中再次显示错误消息。