resueltos - procesos paralelos en java
No se puede crear un controlador dentro del hilo que no haya llamado a Looper.prepare() (6)
Recibo este error "No se puede crear un controlador dentro del hilo que no haya llamado a Looper.prepare ()"
¿Puedes decirme cómo solucionarlo?
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();
}
});
Método de pago inicial:
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);
}
Debes saber que cuando intentas modificar tu IU, el único hilo que puede hacer eso es el UiThread
.
Entonces, si desea modificar su IU en otro hilo, intente usar el método: Activity.runOnUiThread(new Runnable);
Tu código debería ser así:
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();
En lugar de la new Thread()
, intente dar
this.runOnUiThread(new Runnable() {
He encontrado que la mayoría del manejo de hilos puede ser reemplazado por AsyncTasks como esto:
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");
}
}
Paso el contexto de aplicación al Async para que pueda crear diálogos desde él.
La ventaja de hacerlo de esta manera es que usted sabe exactamente qué métodos se ejecutan en su interfaz de usuario y cuáles se encuentran en un hilo de fondo separado. Su subproceso principal de UI no se retrasa, y la separación en pequeñas tareas asíncronas es bastante buena.
El código supone que su método startPayment () no hace nada con la interfaz de usuario, y si lo hace, muévalo a onPostExecute de AsyncTask para que se haga en el hilo de la interfaz de usuario.
Supongo que crea un controlador en el método startPayment (). No puedes hacer eso, ya que los controladores se pueden crear solo en el hilo de la interfaz de usuario. Solo créalo en su clase de actividad.
Tratar
final Handler handlerTimer = new Handler(Looper.getMainLooper());
handlerTimer.postDelayed(new Runnable() {
public void run() {
......
}
}, time_interval});
no puedes cambiar ninguna IU en el hilo, puedes usar runOnUIThread
o AsyncTask
para más detalles sobre esto, AsyncTask
clic aquí