首页 文章

无法在未调用Looper.prepare()的线程内创建处理程序

提问于
浏览
17

我收到此错误“无法在未调用Looper.prepare()的线程内创建处理程序”

你能告诉我怎么解决吗?

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();
        }

    });

StartPayment方法:

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);
}

6 回答

  • 3

    我假设您在startPayment()方法中创建了一个Handler . 您不能这样做,因为只能在UI线程上创建处理程序 . 只需在您的活动类中创建它 .

  • 29

    而不是 new Thread() 行,尝试给予

    this.runOnUiThread(new Runnable() {
    
  • 1

    您无法更改线程中的任何UI,您可以使用 runOnUIThreadAsyncTask 获取有关此click here的更多详细信息

  • 3

    您应该知道,当您尝试修改UI时,可以执行此操作的 only 线程是 UiThread .

    因此,如果要在另一个线程中修改UI,请尝试使用该方法: Activity.runOnUiThread(new Runnable);

    你的代码应该是这样的:

    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();
    
  • 1

    我发现大多数线程处理都可以用AsyncTasks替换,如下所示:

    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");
        }
    }
    

    我将应用程序上下文传递给Async,以便它可以从中创建对话框 .

    这样做的好处是,您确切地知道在UI中运行哪些方法以及哪些方法位于单独的后台线程中 . 您的主UI线程没有延迟,并且分离成小异步任务非常好 .

    该代码假定您的startPayment()方法对UI不执行任何操作,如果是,则将其移动到AsyncTask的onPostExecute中,以便在UI线程中完成 .

  • 1

    尝试

    final Handler handlerTimer = new Handler(Looper.getMainLooper());
            handlerTimer.postDelayed(new Runnable() {
                public void run() {
                                    ...... 
    
                                  }
                                                     }, time_interval});
    

相关问题