Autor: Sebastián Ortiz (página 1 de 12)

java.lang.OutOfMemoryError: Java heap space en Visual Studio con Xamarin

Al desarrollar una app en Visual Studio, aprovechando las ventajas de la nueva y gratuita integración con Xamarin, el compilador nos puede arrojar eventualmente un error del tipo

java.lang.OutOfMemoryError: Java heap space .

Esto ocurre básicamente porque se excede el máximo de memoria alojada (allocated memory) de la pila de instrucciones (heap memory), lo que se puede resolver de dos formas: la primera es colocar un parámetro en tiempo de compilación que aumente ese espacio a 1 Gb o más, y la segunda es cambiar el JDK con el que se esta compilando, ya que por defecto se toma la versión de 32 bits del mismo, y el JDK disponible de 64 bits tiene mayores optimizaciones y licencias que esta versión, por ende, hay que remplazarla.




Remplazar el JDK de 32 bits por el de 64 bits

1. Descargarse e instalar la última versión del JDK de 64 bits.

2. En Visual Studio, ir a Herramientas -> Opciones y luego a Xamarin -> Configuración de Android.

3. En el apartado Java Development Kit Location veremos que la ruta a la que dirige es el JDK de 32 bits. Hacemos clic en Change.

4. En la ventana que se abre, hacemos clic en el botón con los tres puntos para cambiar la ruta del JDK y elegimos la ruta donde se instaló el JDK de 64 bits que descargamos previamente. Normalmente la ruta es C:\Program Files\Java\jdkxxxxx (donde xxxxx es la versión instalada).

5. Aceptamos los cambios, reiniciamos Visual Studio y al volver a compilar veremos que la prueba si pasa.

Compilar con el SDK de 64 bits no afecta en nada a la ejecución de las apps en dispositivos de procesadores arm, x86 o x64, ya que recordemos que las apps se precompilan en este punto y se terminan de compilar en el dispositivo del usuario final.




Sobrevivir a un Cyberday, Cybermonday y otros (I)

Cyberday tecla

En Chile, así como en probablemente muchos países, una o dos veces al año se realizan eventos para “incentivar las compras online de los ciudadanos. Asemejándose al blackfriday gringo, y, más bien, dado nuestro ingente interés por la tecnología, al cybermonday, es que en este caso, en Chile se celebra el Cyberday, o days, debido a que generalmente son 3 o 4 días de “ofertones”.

Como era de esperar, este año acaba de terminar el 4to evento de esta categoría, donde se han sumado casi 100 tiendas online a tratar de capturar al curioso y ávido comprador, y, como era de esperar, muchas de estas tiendas se tomaron a la ligera la carga de posibles clientes, tanto a nivel técnico como comercial.

Es así como en un intento de ayudar a nuestros colegas del área TI, es que detallare algunas sugerencias a considerar para el siguiente evento de estas características.

Leer más →

Fix the Windows Phone Recovery Tool error 0x80091007

e0ed68f3-d9ae-4d25-8409-c2cc80248344

The fix process:

  1. Download this pack of files: http://1drv.ms/1LKvCnq
  2. Run EVERY installation inside EVERY folder EXCEPT the WPRTInstaller.msi from the Packages folder.
  3. Run the oficial Windows Phone Recovery Tool installation, you can download it from this link: http://bit.ly/1E6pYnX
    1. If it works, run the program and follow the steps.
    2. If it not works, run the WPRTInstaller.
  4. Finally, if nothing works, run the WindowsPhoneRecoveryTool.exe inside the Windows Phone Recovery Tool folder as administrator. If a message is shown, créate the folder in the place it says. (commonly, C:\Program Files\Microsoft\Care Suite).




Where did this files come from?

I searched where the official installation puts the files needed to install, so, thats why you need to run EVERY installation inside EVERY folder, except the WPRTInstaller.msi.

It worked for me, after so many suggestions that did not work.

If it was useful, give me a comment 😉

Generación automática de getters, setters y constructores en C#

Una de las características que más me gustan de Netbeans es su posibilidad de generar código repetitivo automáticamente utilizando funciones de generación de código automatizadas presionando alt+insertar en el cuerpo de la clase, tales como la generación de los Inspectores (Getters), Modificadores (Setters) y Constructores, que ahorran tiempo considerablemente y más cuando queremos solo completar la definición de una clase de forma elegante.

En C#, sabemos que los getters y setters se pueden declarar rápidamente en una propiedad (es decir, atributo público cuya asignación o lectura no requerirá de un método particular) usando cualquiera de estos métodos:

//Declaración abreviada
public tipo nombre{get; set;}

//Declaración con miembro privado
private tipo micampo;

public tipo acceso_micampo
{
get{ return micampo; }
set{ micampo = value; }
}

Durante mucho tiempo, pensé que Visual Studio no permitía acelerar esta tarea, ya que aunque es bastante corta la manera de declarar dichos métodos, siempre se agradece no tener que estar copiando y pegando algo que se mantendrá constante para todas las propiedades de una clase. Ademas, a la hora de crear diversos constructores, había que escribirlos a mano, lo cual quita del mismo modo, bastante tiempo.




Para simplificar la generación de código de las propiedades, utilizaremos la función Insertar Fragmento de Código, haciendo clic derecho sobre cualquier parte dentro de una clase y seleccionando C# y luego prop, propg o propfull.

Notar que basta con escribir estas instrucciones en nuestro código y seguido a ello, presionar tab, lo que llamará a la autocompletación de código en plantilla.

//Escribiendo prop + TAB
public TYPE Type { get; set; }

//Escribiendo propg + TAB
public int I { get; private set; }

//Escribiendo propfull + TAB
private int myVar;

public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}

Para la generación de un Constructor, desgraciadamente, Visual Studio no incluye un generador o plantilla que pueda servirnos, pero si utilizamos un plugin como ReSharper (de pago, a no ser que seas un MVP), su generación es muy simple, basta con ir al menú de ReSharper, seleccionar Edit y finalmente Generate Code.

Se abrirá un pequeño menú contextual como el de Netbeans en el cual seleccionamos Constructor y luego, un asistente nos guiará en el resto del proceso.

Llenar de manera asíncrona un combobox (o DropDownList en Razor) en ASP.NET MVC4 a partir de otro combobox

Es común que cualquier formulario que utilicemos en un sitio web llene los combos de selectores de datos a partir de información llenada previamente.

Para este ejemplo, agradezco la ayuda de Camilo Ramirez, quien tiene vasta experiencia en MVC4.

Por ejemplo, al seleccionar un país en un combobox (o select o DropDownList, etcétera), lo esperable es que otro combobox llene las ciudades a partir del país seleccionado en el primer combobox.

En MVC4 tenemos dos formas de hacerlo; la forma sincronía es enviar el valor del primer combo a un controlador, que llene una segunda lista y se envíe a la vista dentro del modelo para desplegar los datos. El problema de esta forma, es que recargaremos la página completa, por lo que si no enviamos los datos ya llenados por el usuario, deberemos generar las rutinas para que los valores de todos los campos se llenen de modo automático.

La segunda forma es hacer que el valor sea envíado a una acción del controlador de manera asíncrona, y los valores sean devueltos utilizando AJAX. Veamos como se hace:

En la Vista, consideremos el siguiente bloque que genera un combo primera-lista a partir de la variable primeraLista:

@{
var primeraLista = new List<object> {new {nombre = "primero", id = 1}, new {nombre = "segundo", id = 2}, new {nombre = "tercero", id = 3}};
}

@Html.DropDownList("primera-lista", new SelectList(primeraLista, "id", "nombre"), new { @id = "primera-lista" })
<select id="segunda-lista"></select>




El siguiente código javascript se encarga de “escuchar” cuando el valor de la lista primera-lista sea cambiado, lo que hará que el valor sea enviado utilizando AJAX a una acción del controlador que alterará el código de la página web de manera asíncrona con los valores retornados:

<script src="~/Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
    $(document).on("ready", function() {
        $("#primera-lista").change(function() {
            idSelected = $(this).val();
            $.ajax({
                url: '@Url.Action("GetSecondValues")'+"?id=" + idSelected,
                type: "POST",
                success: function (data) {
                    var options = "";
                    $.each(data, function(index, value) {
                        options += '<option value="' + value.id + '">' + value.nombre + '</option>';
                    });
                    $("#segunda-lista").html(options);
                },
                error:function() {
                    alert("error...");
                }
            });
        });
    });
</script>

En el controlador generamos una acción con ActionResult que reciba como retorno un objeto JSON con la lista de elementos a cargar dependiendo del valor enviado desde el combo primera-lista. Notar que la lista se crea en este momento, por lo que podemos invocar un webservice o rutina a una base de datos para llenar esta lista:

 public ActionResult GetSecondValues(int id)
        {
            List<object> devolver;
            switch (id)
            {
                case 1:
                    devolver = new List<object>
                                   {
                                       new {nombre = "hola1.1", id = 1},
                                       new {nombre = "hola1.2", id = 2},
                                       new {nombre = "hola1.3", id = 3}
                                   };
                    break;
                case 2:
                    devolver = new List<object>
                                   {
                                       new {nombre = "hola2.1", id = 1},
                                       new {nombre = "hola2.2", id = 2},
                                       new {nombre = "hola3.3", id = 3}
                                   };
                    break;
                case 3:
                    devolver = new List<object>
                                   {
                                       new {nombre = "hola3.1", id = 1},
                                       new {nombre = "hola3.2", id = 2},
                                       new {nombre = "hola3.3", id = 3}
                                   };
                    break;
                default:
                    devolver = new List<object>
                                   {
                                       new {nombre = "default1", id = 1},
                                       new {nombre = "default2", id = 2},
                                       new {nombre = "default3", id = 3}
                                   };
                    break;
            }
            return Json(devolver);
        }