Ich erhalte diesen Fehler "Handler kann nicht in Thread erstellt werden, der nicht Looper.prepare () aufgerufen hat"
Kannst du mir sagen, wie ich es reparieren kann?
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-Methode:
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);
}
Sie sollten wissen, dass wenn Sie versuchen, Ihre Benutzeroberfläche zu ändern, der only - Thread, der dies tun kann, die UiThread
ist.
Wenn Sie also Ihre Benutzeroberfläche in einem anderen Thread ändern möchten, verwenden Sie die Methode: Activity.runOnUiThread(new Runnable);
Ihr Code sollte so aussehen:
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();
Ich gehe davon aus, dass Sie einen Handler in der startPayment () -Methode erstellen. Das ist nicht möglich, da Handler nur im UI-Thread erstellt werden können. Erstellen Sie es einfach in Ihrer Aktivitätsklasse.
Versuchen Sie, anstelle von new Thread()
zu geben
this.runOnUiThread(new Runnable() {
sie können keine Benutzeroberfläche in Thread ändern. Sie können runOnUIThread
oder AsyncTask
verwenden, um weitere Informationen zu diesem Thema zu erhalten klicken Sie hier
Ich habe festgestellt, dass die meisten Thread-Aktionen wie folgt durch AsyncTasks ersetzt werden können:
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");
}
}
Ich übergebe den Anwendungskontext an den Async, damit Dialoge erstellt werden können.
Dies hat den Vorteil, dass Sie genau wissen, welche Methoden in Ihrer Benutzeroberfläche ausgeführt werden und welche sich in einem separaten Hintergrundthread befinden. Ihr Haupt-UI-Thread wird nicht verzögert, und die Trennung in kleine asynchrone Aufgaben ist ziemlich schön.
Der Code geht davon aus, dass Ihre startPayment () -Methode nichts mit der Benutzeroberfläche tut. Wenn dies der Fall ist, verschieben Sie sie in die onPostExecute-Datei der AsyncTask, sodass dies im UI-Thread erfolgt.
Versuchen
final Handler handlerTimer = new Handler(Looper.getMainLooper());
handlerTimer.postDelayed(new Runnable() {
public void run() {
......
}
}, time_interval});