Can't create handler inside thread that has not called Looper.prepare()

前端 未结 6 1709
我寻月下人不归
我寻月下人不归 2020-12-03 16:50

I get this error \"Can\'t create handler inside thread that has not called Looper.prepare()\"

Can you tell me how to fix it?

public class PaymentAc         


        
相关标签:
6条回答
  • 2020-12-03 17:32

    You should know that when you try to modify your UI , the only thread who can do that is the UiThread.

    So if you want to modify your UI in another thread, try to use the method: Activity.runOnUiThread(new Runnable);

    Your code should be like this :

     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();
    
    0 讨论(0)
  • 2020-12-03 17:35

    Try

    final Handler handlerTimer = new Handler(Looper.getMainLooper());
            handlerTimer.postDelayed(new Runnable() {
                public void run() {
                                    ...... 
    
                                  }
                                                     }, time_interval});
    
    0 讨论(0)
  • 2020-12-03 17:36

    I assume you create a Handler in startPayment() method. You can't do that, as handlers can be created on th UI thread only. Just create it in your activity class.

    0 讨论(0)
  • 2020-12-03 17:43

    Instead of new Thread() line, try giving

    this.runOnUiThread(new Runnable() {
    
    0 讨论(0)
  • 2020-12-03 17:54

    I've found that most thread handling can be replaced by AsyncTasks like this:

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

    I pass in the Application Context to the Async so it can create dialogs from it.

    The advantage of doing it this way is you know exactly which methods are run in your UI and which are in a separate background thread. Your main UI thread isn't delayed, and the separation into small async tasks is quite nice.

    The code assumes your startPayment() method does nothing with the UI, and if it does, move it into the onPostExecute of the AsyncTask so it's done in the UI thread.

    0 讨论(0)
  • 2020-12-03 17:57

    you cant change any UI in thread you can use runOnUIThread or AsyncTask for more detail about this click here

    0 讨论(0)
提交回复
热议问题