Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

208
Views
pestillo (utilizado para esperar la respuesta asíncrona) congela el WebView (y la interfaz de usuario)

Tengo una aplicación que muestra una vista web en todo el diseño. A veces necesito llamar a un método asíncrono, esa operación asíncrona la realiza un sdk de terceros, y luego espero por un tiempo hasta que obtengo la respuesta a un oyente designado. Lo resolví con un pestillo: una vez que se recibe la respuesta en el oyente, hago una cuenta regresiva del pestillo y luego el método de inicio puede continuar con esta respuesta. Desafortunadamente, cuando hago esto, WebView se atasca. Me imaginé que la interfaz de usuario nativa estaría atascada, pero no esperaba que la vista web también se congelara. ¿Cómo se puede superar eso?

Para que quede más claro, aquí hay un ejemplo. Necesito que ajaxFunc espere hasta que MyAsyncListener obtenga una determinada respuesta y luego devuelva esta respuesta exacta.

parte de JS que inyecto en la vista web:

 var response = jsHandler.ajaxFunc(request.data);

Tengo una variable global variable llamada response .

 public class JavaScriptInterface { @JavascriptInterface public String ajaxFunc(String data) { return MyUtils.handleData( data ); } }

el método handleData:

 public String handleData( String data ) { SomeClass.startAsyncRequest(); // starts the async request, response is to come at the listener's callbacks . latch = new CountDownLatch(1); try { latch.await(30, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } return response; }

ahora, una vez que la función handleData llama a una función, que hace algo de forma asíncrona, la función asíncrona devuelve alguna respuesta dentro de algún Oyente:

 myAsyncListener = new MyAsyncListener() { @Override public Response handleEvent(CustomEvent event) { //Now I need to return this 'event' back to the handData/ajaxFunc function <-- response = event.getName(); latch.countDown(); } });
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Necesito que ajaxFunc espere hasta que MyAsyncListener obtenga una determinada respuesta y luego devuelva esta respuesta exacta.

Dado que está enviando una solicitud asíncrona, no debe esperar que la respuesta llegue en la misma llamada al método que realizó para iniciar el código asíncrono. Si hace esto, el subproceso de la persona que llama se bloqueará hasta que llegue la respuesta asíncrona, es decir, no será asíncrono en absoluto.

Puede rediseñar su código a algo como esto:

 public class JavaScriptInterface { @JavascriptInterface public void ajaxFunc(String data) { // draw a waiting animation or something MyUtils.handleData(data); } }
 public void handleData(String data) { SomeClass.startAsyncRequest(); }
 myAsyncListener = new MyAsyncListener() { @Override public void handleEvent(CustomEvent event) { // Do what you need to do // (update UI, call javascript etc.). // // Mind the thread that will execute this callback // to prevent multithreading issues. } }
over 4 years ago · Santiago Trujillo Report

0

Ha puesto CountDownLatch dentro de su código, lo que provocará el bloqueo de su hilo principal. Esa es la razón del retraso en la interfaz de usuario.

Para mejorar, debe mostrar algo de ProgressDialog antes de realizar el trabajo principal de la tarea Async que generalmente se escribe en el método doInBackground() de la tarea Async y ocultarlo después de completar su tarea, Async proporciona el método onPostExecute() para ese propósito.

Si necesita poner un tiempo de espera como lo está haciendo su CountDownLatch , puede escribir el temporizador en doInBackground() de Async. Ese temporizador detendrá su Async actual y habrá transcurrido el tiempo asignado.

Actualización, podría usar EventBus para su propósito:

EventBus funciona con el patrón de publicación/suscripción. Puede suscribirse en Activity y publicar el resultado desde JavaScriptInterface .

Agréguelo en gradle usando -

 compile 'org.greenrobot:eventbus:3.0.0'

En su Activity , comience a suscribirse, generalmente suscripciones realizadas en el método onCreate de Activity :

 EventBus.getDefault().register(this);

También elimine las suscripciones en el método onDestroy de Activity o si su trabajo está terminado.

 EventBus.getDefault().unregister(this);

Para escuchar la suscripción, use el siguiente código en su Activity :

 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MyMessageEvent event) { // Do your work after getting result from ajaxFunc method };

Solo tiene que publicar una notificación de mensaje desde su método ahora y eliminar el pestillo CountDown de su código si no se necesita en otro lugar.

 myAsyncListener = new MyAsyncListener() { @Override public Response handleEvent(CustomEvent event){ response = event.getName(); // Create object of message and post it final MyMessageEvent msgEvent = new MessageEvent(response); EventBus.getDefault().post(msgEvent); } });

MiEventoDeMensaje.clase

 import android.support.annotation.NonNull; public class MyMessageEvent { private String mMessage; public MyMessageEvent(@NonNull final String message) { mMessage = message; } public String getMessage() { return mMessage; } }
over 4 years ago · Santiago Trujillo Report

0

Modelo de subproceso de Android

Como introdujo JCIP , muchos marcos de interfaz de usuario son de un solo subproceso. Utilizan el confinamiento de subprocesos para evitar interbloqueos e integridad de los datos. Android también usa este modelo de hilo.

De forma predeterminada, todos los componentes de la misma aplicación se ejecutan en el mismo proceso y subproceso (llamado el subproceso "principal").

Entonces, si espera en el hilo principal usando lacth, la interfaz de usuario no se actualizará ni responderá a su acción.

Tarea de fondo

Pero a veces, queremos realizar una tarea de mucho tiempo, como usar la red para descargar algo y leer desde db. Para que la interfaz de usuario responda, debemos realizar esos trabajos en otro subproceso (Aviso: no en el Servicio, que por defecto aún se ejecuta en el subproceso principal).

Manera de Java

Por lo tanto, puede usar el thread o el executor para obtener sus datos, luego volver a leer los datos en el hilo principal como el siguiente método cuando ocurre algún evento:

 Activity.runOnUiThread(Runnable)

Modo Android

O puede usar AsyncTask nativo de Android, que es conveniente. Por ejemplo, cuando desea verificar el nombre de usuario/contraseña del usuario, debe conectarse a su servidor para verificarlo. En tal escenario, puede poner el proceso de solicitud y verificación en una AsyncTask y el subproceso de la interfaz de usuario puede hacer alguna animación cuando no hay respuesta. A continuación se muestra un código:

 public class UserLoginTask extends AsyncTask<Void, Void, Boolean> { private final String mName; private final String mPassword; UserLoginTask(String name, String password) { mName = name; mPassword = password; } // backgroud thread @Override protected Boolean doInBackground(Void... params) { // network access. for (String credential : CREDENTIALS) { String[] pieces = credential.split(":"); if (pieces[0].equals(mName)) { // Account exists, return true if the password matches. return pieces[1].equals(mPassword); } } // register the new account here. return true; } // UI thread @Override protected void onPostExecute(final Boolean success) { mAuthTask = null; showProgress(false); if (success) { // start next finish(); Intent intent = new Intent(LoginActivity.this, Drawer.class); startActivity(intent); } else { mPasswordView.setError(getString( R.string.error_incorrect_password )); mPasswordView.requestFocus(); } } @Override protected void onCancelled() { mAuthTask = null; showProgress(false); } }

Árbitro:

  • Mi blog relacionado con Android Thread
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!