Comunicación entre actividad y servicio. Cambiar entre las pantallas de la aplicación Transmisión de datos entre Activati
De alguna manera, tuve una tarea para transferir datos del servicio a Activat. Comenzó la búsqueda de soluciones en el SDK estándar, pero como no hubo tiempo, luego voló una mala solución como un uso de la base de datos. Pero la pregunta se abrió y después de un tiempo me di cuenta de una forma más correcta, que está en SDK, utilizando las clases de mensaje, controlador, mensajero.
Ocurrencia
Necesitamos transmitir datos de Activat a Service y Atrás. ¿Cómo lo hacemos? Para resolver nuestra tarea, ya tenemos todo lo que necesita. Todo lo que necesita es enlazar el servicio a la atitividad usando Bindservice, transfiera los parámetros deseados y un poco de magia en forma de usar clases de mensajes. Y la magia es usar las variables de instancia de mensajes y, en particular, responda. Esta variable es necesaria para que podamos consultar la instancia de servicio Messanger desde Activati \u200b\u200by en el servicio a la copia de Messanger, una. De hecho, no tan simple. Al menos por mi no la mente más dotada. En parte, solo mejoré la documentación que ya es: servicios también, hay buen ejemplo en StackOverflow. En cualquier caso, espero que el artículo sea útil al menos a alguien y no nos atreví a no en vano.
Ejemplo
Como ejemplo, estamos implementando un servicio que aumentará y reducirá el valor del mostrador y devolverá el resultado en Activati \u200b\u200ben TextView. Se omite el código de diseño, ya que hay dos botones y un campo de texto, todo es simple.
Ventas
Le daré un código completamente activado:
MAINACTENCIA DE CLASE PÚBLICA ANTENDIENDA LA ACTIVIDAD (PUBLICATE FINAL STRING TAG \u003d "TESTSERVICE"; TESTSERVICECONNECCIÓN DE TESTSERVCONN; TESTTTXT TESTTTX; Messenger de Messenger final \u003d Nuevo Messenger (New IncomingHandler ()); Messenger Toservicemessenger; @Override Public Void Oncreate (Súper. OneCreate (SavedInstancestate); setcontentview; testtxtxt \u003d (textView) findworkbyid (r.id.test_txt); enlace (nueva intención), (testservconn \u003d nuevo testserviceconnection ()), contexto .bind_auto_create);) @Override Public Void Onestroy () ( super.ondosdestroy (); Desbordamiento (TestServconn);) Control de voides públicos (botón de vista) (nulo, testservice.count_plus); msg.replyto \u003d messenger; intente (toservicemessenger.send (msg);) captura (e.printstacktrace () ;)) Control de recocrCrCrCrclick (NULL, NULL, TESTSERVICE.COUNT_MINUS); MSG .Replyto. \u003d Messenger; Intente (toservicemessenger.send (msg);) captura (e.printstacktrace ();)) La clase privada incominghandler extiende el controlador (@Override Public Void HandleMessage (Msg.What) (Test Service. Get_count: log.d (etiqueta "( Actividad) ... obtenga contar "); testtxt.settext (" "+ msg.arg1); ruptura;))) Prueba privada de la claseVicServiceconnection Implementa ServiceConnection (@Override Public Void OnServicEnnectect (nombre de componente, servicio de Ibinder) (Toservicemessenger \u003d New Messenger ; // Envíe el valor inicial del mensaje msg \u003d mensaje.obtain contador (nulo, testservice.set_count); msg.replyto \u003d messenger; msg.arg1 \u003d 0; // nuestro contador intento (toservicemessenger.send (msg);) Captura (remoteexcepción E) (E.PrintStackTrace ();)) @Override Public Void OnServiceConnectected (ComponentName Nombre)))
Lo explicaré. Al crear Activat, estamos inmediatamente vinculados al servicio, implementando la interfaz de servicio de servicio y envíe un mensaje al servicio "Establezca el valor del contador", pase a cero y cree un toservicemessanger, pasando la interfaz de Ibinder al diseñador. Por cierto, en el servicio es necesario devolver este Ehemple, de lo contrario habrá NPE. Con esta clase, enviamos el mensaje al servicio. Y aquí es mágico: guardamos nuestra otra instancia de mensajero a la variable de respuesta a la variable, la que recibe una respuesta del servidor y es a través de ella que se comunicará con Activat.
Para recibir un mensaje del servicio, use su manejador y solo busca variables que necesitamos y hagas medidas en ellas. Por clics en los botones (CondeCRCrClick, CondeCrlick Methods), envíe solicitudes al servicio, especificando la acción deseada en el MSG.Qué variable.
Paquete com.example.servicetest; Importar Android.App.Service; Importar Android.Content. *; Importar Android.os. *; Importar Android.os.Process; Importar android.util.log; Testservice de clase pública extiende el servicio (Final de Final de Final de Estático Público \u003d 1; Final estática pública Intinte_minus \u003d 2; Final estático estático INT SET_COUNT \u003d 0; PUBLIC estático estático Final int get_count \u003d 3; INT Count \u003d 0; Inhandler de Messenger Messenger; Messenger toactivitymessenger; @Override Public Void Oncreate () (super.oncreate (); HandlerThread Hilo \u003d Nuevo HandlerThread ("ServicesArtArtArguments", Process.Thread_Priority_Background); Hilo.start (); Inhandler \u003d New IncomingHandler (hilo.getlooper ()); Messanger \u003d Nuevo Messenger (inhandler);) @Override Public Ibinder Onbind (Regreso Messanger.getBinder ();) @Override Public Intent OnStartCommand (Devolver Start_Sticky;) // Mensaje Handler Actividades Private Class IncomingHandler extiende el manejador (Super Looper) (Looper Looper) (Looper Looper) @Override Public Void Handlemessage (Mensaje Mensaje) (//Super.Handlemessage(msg); TactivityMess enger \u003d msg.replyto; Interruptor (msg.what \u003d msg.arg1; log.d (mainactivity.tag "," (servicio) ... set cuenta "); descanso; Case cuenta_plus: Count ++; log.d (mainactivity.tag" (servicio ) ... cuenta plus "); descanso; Case cuenta_minus: log.d (mainactivity.tag," (servicio) ... contar menos "); cuenta--; romper;) // enviar un valor medidor en el mensaje de activación OUTMSG \u003d Message.Obtain (inhensa, get_count); OUTMSG.ARG1 \u003d CUENTA; Outmsg.Replyto \u003d Messanger; Intente (si (toActivityMessenger! \u003d Null) toactivitymessenger.send (upmsg);) captura (e.printstacktrace ();))))
Todo por analogía con lógica en Activiti. Ni siquiera sé si necesitas explicar algo. El único momento es que inmediatamente envíe una solicitud de vuelta a Activat en HandleMessage, usando la variable Magic Variables PonyTo y tirar del mensajero anterior arriba. Y el segundo momento que ya dije es:
@Override Public Ibinder Onbind (Intención ARG0) (devuelva Messanger.getBinder ();)
sin que todo cae. Es esta instancia de la interfaz que se transmitirá a ServiceConnection.
Conclusión
En general, todo. Tal ejemplo de interacción de la interacción de la activación y el servicio. Me parece que la interacción no trivial es bonita, aunque alguien puede parecer lo contrario.
Preguntas, aclaraciones y otros en PM. Puede haber inexactitudes sobre cualquier aspecto, así que siéntase libre de escribir y enderezar.
Espero que la publicación sea útil para los lectores.
Última actualización: 04/03/2018
Para transferir datos entre dos actividades, se utiliza un objeto de intención. A través de su método PUTEXTRA (), puede agregar la clave y el valor asociado.
Por ejemplo, transmitiendo desde la actividad actual en las cadenas de "Hello World" con la clave "Hola":
// creando un objeto de intención para iniciar la secundaria Intens intens \u003d nueva intención (esta, la segundaCertivity.class); // Transferencia de un objeto con la tecla "Hola" y el valor "Hello World" de intent.putextra ("Hola", "Hello World"); // iniciar la iniciación de la secundaria (intención);
El método PUTEXTRA () se usa para transmitir datos, que como un valor le permite transferir los tipos más simples de datos de tipo: cadena, int, flotador, doble, largo, corto, byte, char, las matrices de estos tipos, o el Objeto de interfaz serializable.
Para obtener los datos enviados al cargar la secundación, puede usar oBTENER.(), en el que se transmite el objeto:
Argumentos del paquete \u003d getIntent (). GetExtras (); Nombre de la cadena \u003d argumentos. Post ("hola"). Tostring (); // Hola Mundo.
Dependiendo del tipo de datos enviados, cuando se recibe, podemos usar varios métodos de objeto de paquete. Todos ellos aceptan la clave de objeto como un parámetro. Los principales son:
obtener (): método universalque devuelve el valor del tipo de objeto. En consecuencia, el campo de recibo debe convertirse en el tipo deseado
getstring (): devuelve la cadena de tipo de objeto
getint (): devuelve el valor del tipo int
getByte (): Devuelve el valor del tipo de byte
getchar (): devuelve el valor de tipo char
getshort (): devuelve un valor de tipo corto
getlong (): devuelve un valor largo
getfloat (): devuelve el valor del tipo flotante
getDouble (): devuelve un valor doble
getBoolean (): devuelve un valor de tipo booleano
getChararray (): devuelve una matriz de objetos de char
getintarray (): devuelve una matriz de objetos INT
getfloatarray (): devuelve una matriz de objetos de flotador
getSerializizable (): devuelve el objeto de interfaz serializable
Permítanos en el proyecto se definirá dos actividades: la principal autorización y la secundabilidad.
En el código de la secundaria determinaremos los datos que obtienen:
Paquete com.example.eugene.serializEapp; Importar android.support.v7.app.appCompatactivity; Importar android.os.bundle; Importar Android.Widget.TextView; La segunda licitación de la clase pública se extiende la compatibilidad de la aplicación (@Override protegido de Void Oncreate (Bundle SavedInstanceStancate) (super.oncreate (SavedInstancuestro); TextView TextView \u003d Nuevo TextView (esto); TextView.SetaxTsize (20); TextView.SETPADDING (16, 16, 16, 16 16 ); Argumentos del paquete \u003d getIntent (). GetExtras (); ¿Si (argumentos! \u003d Nulo) (Nombre de la cadena \u003d argments.get). Tostring (); String Company \u003d arguments.gentstring ("empresa"); int precio \u003d argumentos getint ("precio"); textView.settxt ("Nombre:" + Nombre + "\\ NCompany:" + Company + "\\ nPrecio:" + Precio);) SetContentView (TextView);)))
En este caso, en la segunda licitación obtenemos todos los datos del objeto del paquete y se muestran en el cuadro de texto TEXTVIEW. Se supone que esta actividad se transmitirá tres elementos: dos filas con nombres y claves de la empresa y una clave con un precio clave.
Ahora definiremos la transferencia a la secundaria de los datos. Por ejemplo, definimos la siguiente interfaz para la principal autorización en el archivo Activity_Main.xml:
Aquí hay tres campos de texto para la entrada de datos y un botón.
En la clase principal, definimos los siguientes contenidos:
Paquete com.example.eugene.serializEapp; Importar Android.Content.Intent; Importar android.support.v7.app.appCompatactivity; Importar android.os.bundle; Importar android.view.view; Importar android.widget.editText; La principal capacidad de clase, la principal sostiene la compatibilidad de la aplicación (@override protegido por el vacío Oncreate (Bundle SavedInstanceStancate) (Super.Onscreate (SavedInstancestate); setcontentview (r.layout.citivity_main);) Void público ONCLICK (VIEW V) (Final EditText NameText \u003d FindViewByID (R.ID .Name); Final EditText CompanyText \u003d FindViewById (r.id.Company); Final EditText PrichExt \u003d FindViewByID (r.id.price); String Name \u003d NameText.GetText (). Tostring (); String Company \u003d CompanyText.getText ( ) .Tostring (); int precio \u003d entero.parseint (pricExt.getText (). Tostring ()); Intens Intens \u003d Intent intent (esto, secundátivity.class); intent.putextra ("nombre", nombre); intención PUTEXTRA ("Empresa", Empresa); intent.putextra ("Precio", Precio); Startactivity (intención);)
En el botón presionando el botón, obtiene los datos ingresados \u200b\u200ben campos de texto, datos y transmitirlos al objeto de intención utilizando el método PUTEXTRA (). Luego lanza la secundaria.
Como resultado, cuando hace clic en el botón, inicia la segunda licitación, que recibirá algunos datos ingresados \u200b\u200ben los campos de texto.
Transferencia de objetos complejos.
En el ejemplo, se transmitieron datos simples: números, líneas. Pero también podemos transmitir datos más difíciles. En este caso, se utiliza el mecanismo de serialización.
Por ejemplo, la Clase de producto definiremos en el proyecto:
Paquete com.example.eugene.serializEapp; Importar java.io.Serializable; Implementos de productos de clase pública Serializable (Nombre de la cadena privada; Empresa de cadena privada; Precio privado int; producto público (nombre de cadena, compañía de cadenas, precio int) (este nombre \u003d nombre; esta.price \u003d compañía; esto.price \u003d precio;) Cadena pública getName () (Nombre de la devolución;) Public Void SetName (Nombre de la cadena) (este nombre \u003d nombre \u003d nombre;) Cadena pública GetCompany () (Compañía de retorno;) Public Void SetCompany (String Company) (Compañía de STRING) (THE.COMPANY \u003d EMPRESA;) Public INT GetPrice () (Precio de devolución;) Public Void setprice (int precio) (este.price \u003d;))
Vale la pena señalar que esta clase implementa la interfaz serializable. Ahora cambiarás el código de la principalistencia:
Paquete com.example.eugene.serializEapp; Importar Android.Content.Intent; Importar android.support.v7.app.appCompatactivity; Importar android.os.bundle; Importar android.view.view; Importar android.widget.editText; La principal capacidad de clase, la principal sostiene la compatibilidad de la aplicación (@override protegido por el vacío Oncreate (Bundle SavedInstanceStancate) (Super.Onscreate (SavedInstancestate); setcontentview (r.layout.citivity_main);) Void público ONCLICK (VIEW V) (Final EditText NameText \u003d FindViewByID (R.ID .Name); Final EditText CompanyText \u003d FindViewById (r.id.Company); Final EditText PrichExt \u003d FindViewByID (r.id.price); String Name \u003d NameText.GetText (). Tostring (); String Company \u003d CompanyText.getText ( ) .Tostrando (); int precio \u003d entero.parseint (pricExt.getText (). Tostring ()); Producto de producto \u003d Nuevo producto (nombre, compañía, precio); intención intencional \u003d nueva intención (esta, la secundaria.clase); Intent.putextra (producto.class.getsimplename (), producto); Startactivity (intención);))
Ahora, en lugar de tres datos dispersos, se transmite un objeto de producto. Como clave, el resultado es el resultado del método producto.class.getsimplename (), que esencialmente está devolviendo el nombre de la clase.
Y cambia la clase de segunda licitación:
Paquete com.example.eugene.serializEapp; Importar android.support.v7.app.appCompatactivity; Importar android.os.bundle; Importar Android.Widget.TextView; La segunda licitación de la clase pública se extiende la compatibilidad de la aplicación (@Override protegido de Void Oncreate (Bundle SavedInstanceStancate) (super.oncreate (SavedInstancuestro); TextView TextView \u003d Nuevo TextView (esto); TextView.SetaxTsize (20); TextView.SETPADDING (16, 16, 16, 16 16 ); Argumentos del paquete \u003d getIntent (). GetExtras (); producto del producto final; si (argumentos! \u003d Null) (producto \u003d (producto) argumentos.getserializable (producto.class.getsimplename ()); textView.settxt ("Nombre: "+ Producto.getName () +" \\ NCompany: "+ Product.getcompany () +" \\ nprice: "+ string.valueof (producto.getPrecio ()));) SetContentView (TextView)))))
El método GetSerializizable () se aplica para obtener datos, ya que la clase del producto implementa la interfaz serializable. Por lo tanto, podemos transmitir un solo objeto en lugar de una marcación de datos dispares.
Hola.
Debe pasar los datos obtenidos a través de UART en la actividad. Esto se puede hacer creando un flujo en la actividad en la que organizar mientras que el ciclo (! Isinterrupted ()) y enviar datos del búfer UART. Después de eso, llamando a la flujo de actividad de la UI - Mainactividad. Esto.Runonuithread (Nuevo Runnable (), realice las acciones necesarias con esta actividad. Pero si llamamos a otra actividad de la actividad principal, entonces el hilo organizado no permite transmitir Datos a la actividad recién creada. Si entiendo correctamente, de modo que los datos de la corriente se pueden transferir a cualquier actividad, el flujo debe crearse no en la actividad, sino en el servicio.
Pregunta: UAR ha recibido datos, en el flujo (que se crea en el servicio), es necesario transferir datos a la actividad, que ahora está activa, ¿cómo se puede hacer esto y se hace en absoluto?
1 respuesta
En cada actividad, crea controlador. En el método ONRESUME (), esta actividad hace que Bindservice (). Allí, uno de los parámetros es la recompensa de la interfaz. La implementación de él es al menos la misma actividad. Implementar en él en el servidorConnectected (). En esta devolución de llamada, uno de los parámetros llega al propio servicio. Así que llame al SetHandler () de este servicio. Pase el manejador allí, que está en la actividad actual. Y aquí están los datos entrantes en el servicio UART en este controlador. Por cierto, el manejador trabaja tradicionalmente en el hilo principal, por lo que no será necesario realizar runonuithread.
La aplicación no siempre consiste en una pantalla. Por ejemplo, creamos muy. programa útil Y quiero conocer al usuario que es su autor. Presiona el botón "Acerca del programa" y cae en nueva pantallaDonde información útil sobre la versión del programa, el autor, la dirección del sitio, cuántos gatos del autor, etc. Percibe la pantalla de actividad como una página web con un enlace a otra página. Si miras el código en el archivo. Mainactividad.Java. De las lecciones anteriores, verás que nuestra clase. Actividad principal. También se refiere a Actividad (o sus herederos) o, dado más precisamente, heredados de él.
La principal capacidad de clase pública extiende la compatibilidad de la aplicación
Como es fácil de adivinar, debemos crear una nueva clase, que puede ser similar a Actividad principal. Y luego, de alguna manera, cambie a ella cuando presione el botón.
Para el experimento, tomaremos el programa desde la primera lección y utilizaremos el botón para experimentos (o crear un nuevo proyecto con un botón en la pantalla). A continuación, cree un nuevo formulario para mostrar. información útil. Por ejemplo, muestre al usuario que haga un gato cuando salga a la izquierda y hacia la derecha. De acuerdo es muy información importanteDando la llave al universo inmóvil.
Crear nueva actividad será manualmente, aunque en el estudio hay plantillas listas. Pero no hay nada complicado y para una mejor comprensión, es útil hacer todo con las manos.
Crear un nuevo archivo de marcado XML actividad_about.xml. en carpeta res / diseño.. Haga clic derecho en la carpeta diseño. y seleccione del menú contextual Nuevo | Archivo de recursos de diseño.. Aparece un cuadro de diálogo. En el primer campo ingrese el nombre del archivo. activity_about. En el segundo, debe ingresar al elemento raíz. Predeterminado se encuentra Restricción. Lavamos el texto y entramos. ScrollView.. Entrada Múltiples caracteres es suficiente para que el estudio sugiera opciones preparadas, puede presionar inmediatamente Entrar, sin esperar la palabra Entrada completa:
Resulta el billete correspondiente en el que el elemento insertará Vista de texto..
La información se eliminará de los recursos, a saber, desde un recurso de cadena. sobre texto.. Ahora se resalta en rojo, señalando sobre la ausencia de información. Fue posible hacer clic Alt + entrar. E ingrese texto en el cuadro de diálogo. Pero para nuestro ejemplo, este método no se adaptará, ya que nuestro texto será multiplicado, utilizando caracteres de control. Por lo tanto, proceder de una manera diferente. Abrir documento. res / valores / strings.xml Y ingrese el siguiente texto manualmente:
Utilizamos las etiquetas de formato de texto de tipo HTML más simples , , . Por nuestro ejemplo, es suficiente para resaltar las palabras grasas que pertenecen al gato y la dirección del movimiento. Para transferir texto a nueva cadena Usar símbolos \\ N.. Agregue otro recurso de cadena para el encabezado de la nueva pantalla:
Marcado descuidado. A continuación, necesitas crear una clase para la ventana. Sobreactividad.java.. Seleccione en el menú Archivo | Nuevo | Clase de java. y llenar los campos adecuados. Al principio, es suficiente para especificar solo el nombre. Luego desastre con otros campos.
Obtenemos la pieza de trabajo.
Ahora la clase está casi vacía. Añadir el código manualmente. La clase debe ser heredada de la clase abstracta Actividad o sus parientes como Fragmentación., Appcompativity. etc. Terminar extiende la actividad.. La clase de actividad debe tener un método. encreate (). Ponemos el cursor del mouse dentro de la clase y eligimos en el menú. Código | Anular los métodos. (Ctrl + O). En el cuadro de diálogo Estamos buscando la clase deseada, puede marcar los primeros caracteres para buscar rápidamente en el teclado. En el método creado, debe llamar al método. setcontentview ()que cargará el marcado preparado en la pantalla. Tendremos esta opción.
Paquete ru.alexanderklimov.helloworld; Importar android.app.activeivity; Importar android.os.bundle; / ** * creado por Alexander Klimov el 01.12.2014. * / Clase pública La altaactividad extiende la actividad (SavedInstancestate); setcontentview (r.layout.activity_about);))
Ahora comienza lo más importante. Nuestra tarea es ir a una nueva pantalla al hacer clic en el botón en la primera pantalla. Volver a clase Actividad principal.. Escribimos un clic Handler:
Vacío público OnClick (Planesantividad. Esta, Aceaactivity.Class); Startactivity (intención);)
Aquí usé una manera de manejar el botón presionando cuyo se le dijo en la clase.
Para iniciar una nueva pantalla, debe crear una instancia de clase. Intención. y especifique la clase actual en el primer parámetro, y en la segunda - la clase para la transición, lo tenemos Sobreactividad.. Después de eso, se llama el método. iniciar actividad ()que lanza una nueva pantalla.
Si ahora intenta verificar el funcionamiento de la aplicación en el emulador, recibirá un mensaje de error. que hicimos mal? Nos perdimos un paso importante. Necesita registrarse nuevo Actividad En manifiesto Androidmanifest.xml.. Encuentre este archivo en su proyecto y haga clic dos veces. Se abre una ventana de edición de archivos. Agregar nueva etiqueta
Así que el recurso de cadena fue útil. sobre_title.. Ejecute la aplicación, haga clic en el botón y obtenga una ventana Sobre el programa. Así que aprendimos cómo crear una nueva ventana y llamarlo para hacer clic en el botón. Y a nuestra disposición apareció un programa MegaUdabal, ahora siempre habrá una pista en cuestión, lo que hace que un gato cuando salga.
Miro de nuevo que la segunda clase de actividad creada debe ser heredada de la clase. Actividad o él como ( Listactividad. ), tenga un archivo de marcado XML (si es necesario) y se registre en el manifiesto.
Después de llamar al método iniciar actividad () Se lanzará nueva actividad (en este caso Sobreactividad.), será visible y se mueva en la parte superior de la pila que contenga los componentes de trabajo. Al llamar a un método tERMINAR () De la nueva actividad (o cuando presiona la tecla de hardware de retorno), se cerrará y se eliminará de la pila. El desarrollador también puede pasar a la actividad anterior (oa a otra) utilizando el mismo método iniciar actividad ().
Crea una tercera pantalla: una forma de perezoso
Los programadores, como los gatos, son criaturas perezosas. Recuerde constantemente que para la actividad necesita para crear un marcado y una clase que se hereda de Actividad, y luego no olvide registrar la clase en el Manifiesto, sí, Nafig.
En este caso, seleccione en el menú. Archivo | Nuevo | Actividad | Actividad básica (u otra plantilla). Además, aparecerá una ventana familiar para crear una nueva actividad. Llene los campos necesarios.
Haga clic en el botón TERMINAR. Y la actividad estará lista. Para asegurarse de que, abra el archivo manifiesto y verifique la disponibilidad. nueva grabación. Ya no digo acerca de los archivos de la clase y Markup, aparecerán frente a usted.
Agregar solo botón de nuevo En la pantalla de actividad principal y escriba el código para la transición a la actividad creada.
Al principio, le aconsejaría que cree manualmente todos los componentes necesarios para la nueva actividad para comprender la relación entre la clase, Markup y Manifesto. Y cuando tenga una mano, puede usar el asistente de creación de actividades para acelerar el trabajo.
Transmisión de datos entre actividades.
Nosotros usamos el ejemplo más simple Para llamar a otra pantalla de actividad. A veces se requiere no solo llamar a una nueva pantalla, sino que también transfiere datos. Por ejemplo, el nombre de usuario. En este caso, necesitas usar un área especial. extradatos.que está disponible en clase Intención..
Región extradatos. - Esta es una lista de parejas. valor claveque se transmite junto con la intención. Las líneas se utilizan como llaves, y para valores, puede usar cualquier tipo primitivo de datos, matrices primitivas, objetos de clase Manojo. y etc.
Para la transferencia de datos a otro método de actividad se utiliza. pUTEXTRA ():
Intent.putextra ("clave", "valor");
Tomar actividad debe causar algún método adecuado: getintextra (), getstringextra () etc.:
INT Count \u003d getIntent (). Getintextra ("nombre", 0);
Remandamos el ejemplo anterior. Ya tenemos tres actividades. En la primera actividad se colocarán dos campos de texto y un botón. Apariencia Puede ser el siguiente:
En la segunda actividad. La secundabilidad. Elemento de instalación Vista de texto.donde mostraremos el texto obtenido de la primera actividad. Escribimos el siguiente código para el método. encreate () En segunda actividad.
@Override Protegido Void Oncreate (Bundle SavedInstancestate) (Super.Onscreate (SavedInstancuestro); SetContentView (R.Layout.Activity_Second); String User \u003d "Zhyvotnyh"; Regalo de cadena \u003d "Hole Donut"; TEXTVIEW INFOTEXTVIAR \u003d (TextView) FindViewByID (R .Id.TextViewInFO); infotExtView.settext (Usuario + ", fue enviado" + regalo);)
Si inicia el programa ahora y simplemente llame a la segunda ventana, como se describe en la primera parte del artículo, veremos la inscripción predeterminada Amarillado, pasaste un agujero desde el panecillo.. De acuerdo, es bastante ofensivo recibir dichos mensajes.
Yo fizo la situación. Añadir código de la primera actividad:
View Void Onclick (View View) (EditText userEditText \u003d (editText) FindViewById (r.id.edittExtuser); EditText GiftEditText \u003d (EditText) FindViewById (r.id.edittExtgift); intención intent \u003d nueva intención (principalactividad. Esta, la secundaria. Clase) / // En la tecla Nombre de usuario, le pihem texto desde el primer campo de texto intent.putextra ("nombre de usuario", userdittextx.gettext (). Tostring ()); // B Tecla regalo PIHAM Texto del segundo campo de texto Intent.putextra ("Regalo", regaledetiptxt.gettext (). Tostring ()); Startactivity (intención);)
Colocamos en un contenedor de objetos especiales. Intención. Dos claves con valores que se toman de campos de texto. Cuando el usuario ingresa los datos en los campos de texto, caerán en este contenedor y se transferirán a la segunda actividad.
La segunda actividad debe estar lista para una cálida recepción de los mensajes de la siguiente manera (FAT resaltado).
// Valores predeterminados String User \u003d "Amarillo"; Regalo de cadena \u003d "agujero de la burbuja"; usuario \u003d getIntent (). getExtras (). getstring ("nombre de usuario"); Regalo \u003d getIntent (). GetExtras (). Getstring ("regalo"); Textview infotextview \u003d (TextView) FindViewByID (r.id.TextViewInfo); infotextView.settext (Usuario + ", fue enviado" + regalo);
Ahora el mensaje no se ve así, pero incluso agradable para alguien. En los ejemplos difíciles, es deseable agregar un cheque al procesar datos. Hay situaciones cuando ejecuta la segunda actividad con el tipo de datos vacío nULOLo que puede llevar al colapso de la solicitud.
En nuestro caso, sabemos que estamos esperando un valor de cadena, por lo que el código se puede reescribir:
Intención intent \u003d getIntent (); usuario \u003d intent.getstringextra ("nombre de usuario");
Usuario \u003d getIntent (). Getstringextra ("nombre de usuario");
El programa tiene una desventaja: no está claro de quien nos llevan. Cualquier menta bien educada no tomará un regalo de una fuente anónima. Por lo tanto, como tarea, agregue otro cuadro de texto para ingresar el nombre del usuario que envíe el mensaje.
Google recomienda utilizar el siguiente formato para las teclas: el nombre de su paquete como prefijo, y luego la clave en sí. En este caso, puede confiar en la singularidad de la clave cuando interactúe con otras aplicaciones. Aproximadamente esta:
Public Final Static String user \u003d "ru.alexanderklov.myapp.user";
¿Quién puso el gato Vaska? Recibe el resultado de vuelta
No siempre sucede simplemente transmitir estas otras actividades. A veces necesitas obtener información de otra actividad cuando está cerrada. Si solíamos usar el método. startatoryivity (intención intencional)Luego hay un método relativo. startatoryiforresult (intención de intención, código de solicitud INT). La diferencia entre los métodos es parámetro adicional Código de solicitud.. De hecho, es solo un entero que puedes pensar en ti mismo. Es necesario para distinguir de quién vino el resultado. Supongamos que tienes cinco pantallas adicionales Y le asigna valores de 1 a 5, y en este código puede determinar cuyo resultado debe procesar. Puede usar -1, entonces será equivalente a la llamada del método. iniciar actividad (). No recibiré ningún resultado.
Si usas el método startatoryiforresult ()Necesita anular el método en el código para recibir el resultado. onactivityResult () y procesar el resultado. ¿Confundido? Vamos a preguntarnos el ejemplo.
Supongamos que eres un ciervo. Se recibió información que se robaron dos tomas de salchichas y otros productos del restaurante de la mesa de una persona influyente. Sospusoramiento Palo en tres sospechosos: cuervo, jodido coño y gato Vaska.
Uno de los visitantes proporcionó una serie de fotos de su iPhone de polvo:
También hay una indicación de otro testigo: Y Vaska escucha, sí come.
Crear un nuevo proyecto Sherlock Con dos actividades. En la primera pantalla, habrá un botón para cambiar a la segunda pantalla y la etiqueta de texto en la que se mostrará el nombre del ladrón.
En la segunda pantalla habrá un grupo de interruptores:
Dado que esperaremos una respuesta de la segunda pantalla, necesitamos usar el método startatoryiforresult () En la primera pantalla en la que le daremos una variable. Elegir_thief. como parámetro Código de solicitud..
Final estático privado en elegir_thief \u003d 0; Vacío público ONCLICK (VIEW V) (MainActividad. Esta, Chooseactivity.Class); StartactivityForResult (CRIPTADIENTE, ELEGIENDE_THIEF);)
Mira el código. Cuando hace clic en el botón, vamos a trabajar con la segunda pantalla. Chooseactividad. Y lanzar la segunda pantalla con la expectativa del resultado.
Ir a la segunda pantalla y escribirá código para la segunda actividad.
Public Final Static String Thief \u003d "ru.alexanderklov.sherlock.thief"; Vacío público Onradioclick (Vista V) (Intención AnswerIntent \u003d New Intent (); Interruptor (V.GetID ()) (Caso R.ID.RadioDiG: APhONESTENTENTENT.PUTEXTRA (Ladrón, "Jodido PUSSY"); Break; Case R.ID .radiocrow: answerintent.putextra (ladrón, "cuervo"); descanso; caso r.id.radiocat: answerintent.putextra (ladrón, "caballo de PRZHEVALSKY"); ROTAZA; DEFAULTE: ROPE;) SETRESULT (resultado_OK, ABSPONSERIENTE); Finalizar ();)
Aquí, todo es simple cuando el detective elige el nombre del criminal, luego a través del método. pUTEXTRA () Pasamos el nombre de la clave y su valor.
Por conveniencia, después de seleccionar, inmediatamente cerramos la segunda ventana y transmitimos el valor antes de cerrar. Resultados.De modo que estaba claro que se hace la elección. Si el usuario cierra la pantalla a través del botón Atrás, se transmitirá el valor. Resultados..
Método seresult () Toma dos parámetros: el código resultante y el resultado se presenta en forma de intención. El código resultante sugiere lo que el resultado finalizó el trabajo de actividad, como regla general, ya sea Activity.Result_Ok.ya sea Activity.Result_Canceled.. En algunos casos, debe usar su propio código de reembolso para procesar opciones específicas para sus opciones de aplicación. Método seresult () Admite cualquier valor entero.
Si transmite datos claramente a través del botón, sería bueno agregar un método tERMINAR ()Para cerrar la segunda actividad tan innecesaria. Si la transición se produce a través del botón Atrás, no es necesario hacer esto.
Si la actividad fue cerrada por el usuario cuando se presiona el botón de retorno de hardware o si el método es tERMINAR () fue causado anteriormente que el método seresult ()El código resultante se instalará en Resultados., y la intención de regreso mostrará el valor. nULO.
Regresa a la primera pantalla. La primera pantalla espera una respuesta de la segunda pantalla, por lo que debe agregarse al método del código onactivityResult ().
@Override protegió el vacío de OnactivityResult (TOT Soldscode, INT Code, datos de intenciones) (super.onactivityResult (código de solicitud, código de resultados, datos); TEBTVIEW INFOTEXTVIAR \u003d (TextView) FindViewByID (r.id.TextViewInfo); if (Solicite Código \u003d\u003d Elegirthief) ( if (Resultopode \u003d\u003d Result_OK) (String thiefname \u003d data.getstringextra (chooseacttivity.thief); infoTextView.settxt (thiefname);) else (infotextView.settext ("); // Borrar el texto)))
El método espera que los datos entrantes con el código. Elegir_thief.y si dichos datos llegan, entonces recupera el valor de la clave Chooseacttivity. Utilizando el método getstringextra. El valor obtenido que derivamos en Vista de texto. (variable infinextView.). Si volvimos a la pantalla a través del botón Atrás, simplemente borre el texto.
Al cerrar una subsidiaria dentro del componente principal, el controlador está activado onactivityResult (). Manipulador onactivityResult () Toma varios parámetros.
- Código de solicitud. El código que se utilizó para iniciar la actividad que devuelve el resultado.
- Código de resultados. El código de resultados establecido por subsidiaria e indicando cómo terminó su trabajo. Puede ser cualquier valor entero, pero, como regla, ya sea Activity.Result_Ok.ya sea Activity.Result_Canceled.
- Datos. La intención utilizada para el embalaje de datos devueltos. Dependiendo del propósito de la actividad subsidiaria, puede incluir la ruta URI que representa la parte seleccionada del contenido. Alternativamente (o adiciones), la subsidiaria puede devolver la información en forma de valores simples empaquetados en el parámetro de intención extras.
Si el trabajo de la actividad subsidiaria terminó imprevistos o si el código de resultado no se especificó antes de cerrar, este parámetro será igual a Activity.Result_Canceled..
Ejecute el proyecto, haga clic en el botón y vaya a la segunda pantalla. Elegimos una de las opciones. Si selecciona Crows, la pantalla se cierra y el nombre del Criminal aparecerá en la primera pantalla. Si elige un bocadillo, aparecerá su nombre.
Por cierto, si elige un gato, ¡entonces su nombre no aparecerá! Revisa y mira por ti mismo. ¿Preguntarás por qué? ¡Watson elemental! El criminal no consideró un detalle importante. El restaurante se observó desde la videocámara, y el registro mostró que realmente robó la salchicha y sustituyó al gato. ¡Vaska, espera!
PD Si al principio parecía incomprensible, entonces mucho más claro con mucho. La transmisión de datos entre pantallas se encuentra a menudo en las aplicaciones y no leerá el ejemplo más de una vez.
P.P.S. El mejor pescado - salchicha. Conociendo esta debilidad, no fue difícil sustituir a un gato.
Usar filtros
En el artículo, mostré una forma común de transitar a otra actividad, cuando en el método iniciar actividad () Se indica la clase actual y clase para la conmutación. Por cierto, la clase de actividad no tiene que ser parte de su solicitud. Si conoce el nombre de la clase de otra aplicación, puede ir a ella. Pero puedes ir a otra actividad de otra manera.
En la práctica, se reúne con menos frecuencia, pero puede ser útil. Supongamos que ya tienes la segunda actividad. En el manifiesto agregue un filtro especial para él:
Y ejecute la segunda actividad a través de un botón, haga clic de esta manera.
Vacío público Onclick (nueva intención) (ru.alexanderklimov.testapplication.seconfactivity "));)
Reemplazar cuerda larga En la constante.
Cadena final estática pública Action_Second_Activity \u003d "ru.alexanderklimov.testapplication.seconActivity"; Vacío público ONCLICK (Nueva intención (Action_Second_Activity);)
Así que lo que hicimos. Para la segunda actividad, recetaron el filtro e indicamos el nombre para acción. En atributo android: Nombre.. Por conveniencia, simplemente coloco el nombre completo de la actividad con el nombre del paquete. Diseñador de clase Intención. Tiene varias versiones sobrecargadas. En una de las versiones, puede especificar una cadena para la acción. Indicamos nuestra acción creada, que está escrita en la segunda actividad. El sistema mientras trabajaba navegando los manifiestos de todos. aplicaciones instaladas. Al buscar el cumplimiento, el sistema encuentra nuestro filtro y comienza la actividad deseada.
Por el mismo principio, se pueden iniciar otras actividades. Mira el ejemplo. Si copia un ejemplo para usted mismo y mira la documentación para android.provider.settings.action_airplane_mode_settings.Verá que una constante de cadena corresponde a este código. estático público final java.lang.string action_airplane_mode_settings \u003d "android.settings.airplane_mode_settings". Compara con nuestro código. Puede asumir que la actividad de los ajustes para régimen autónomo Esta cadena se prescribe en el filtro.
Nombre de la categoría del filtro android.intent.category.default. Dice el sistema que se debe realizar la acción predeterminada, a saber, ejecutar la actividad. Hay otros nombres que no están interesados \u200b\u200ben nosotros.
Y ahora la pregunta está en el relleno. ¿Qué sucede si crea otra actividad y especifica el mismo filtro que la segunda actividad? Y vamos a comprobar. Cree la tercera actividad y copie el bloque con un filtro de la segunda actividad en ella.
Haga clic en el botón en la primera actividad. El sistema le pedirá que elija la opción deseada.
Si seleccionas Siempre, la próxima vez que no tengas que elegir. Para restablecer la selección, vaya a las propiedades de la aplicación en la configuración y localice el botón. Valores predeterminados claros..
Actividad de funcionamiento por su nombre
En el diseñador Intención. El segundo parámetro es clase. Pero supongamos que hay algún tipo de base de datos, donde se indican los nombres de las actividades y debemos ejecutar la actividad necesaria por su nombre. Podemos sobre la base de una variable de cadena para obtener la propia clase y ejecutar la actividad.
Intente (// nombre completo de la clase de actividad de actividad ActivityName \u003d "ru.alexanderklimov.testapplication.seconactivity"; // Recibe el objeto de clase de clase> Myclass \u003d clase.forname (ActivityName); Intención de intención \u003d nueva intención (esto, myclass); Startactivity (intención); ) Captura (ClassNotFoundException E) (E.PrintStackTrace ();)