Categoría: Programación (página 2 de 5)

Depurar paso de parámetros por linea de comandos en C++ con Visual Studio

El paso de parametros desde la linea de comandos a una aplicacion es fundamental para la ejecucion de tareas sin tener que abrir una aplicacion e ingresar los datos a esta. Por ejemplo, el programa format recibe varios parametros previo a su ejecucion.

format C: /s /q

En este caso, se ejecutara format.exe, y se envian a este los parametros C:, /s y /q.

Estos parametros se guardan en el parametro argv de la funcion main del programa, y la cantidad de parametros enviados va asignado al parametro argc de la misma funcion.
Leer más →

Glitch Graphics on Windows Phone Emulator 7.1 with Intel GMA 3000/4000 HD

I wrote this post in english cause this could be more useful in the “international language” than in spanish.
And yes, my english is not perfect.

I never use before the Windows Phone Emulator to run some demos of Windows Phone SDK, but i need it yesterday and i was very confused, cause the graphics in the emulator was really… strange.

The problem is that the screen don’t repaints itself when some “activity” (yes, an Android Developer word wich means view in other software development project) is sended to the front of the screen, resulting some like this:

null

After search a lot, i finally found where is the error: the Intel GMA 4000 HD driver. Unfortunately, Intel seems to not have solution about this, and when i tried to force mi -Optimus- Nvidia GT650M, i discover the frustration about this arquitecture: we can’t force it, in some point, even with the latest Nvidia and Intel video Driver installed, we can’t.

So, after hours, i found some solution coming from the Windows Phone Dev Center, but it was not in the “visible pages”, it was on some comment from some user at the end of a extense discussion about this problem.
Leer más →

For… Each en Java

Utilizar ciclos for para recorrer listas o arreglos, se vuelve ciertamente tedioso al tener que declarar constantemente variables para indizar, otras para calcular el largo de elementos en una lista, y otras para llevar control del ciclo.

Es así como un bloque como este:

for(int i = 0; i < lista.size(); i++)
{
  lista.get(i).setValor(5);
}

Puede abreviarse en uno como este:

for(Operaciones elemento : lista)
{
  elemento.setValor(5);
}

El único inconveniente es que no tendremos control del indice como tal, pero cuando debemos recorrer objetos de la clase Collections, es una forma mucho mas optimizada y elegante de hacerlo.

Uso practico del puntero this en la POO

En lenguajes de programación orientada a objetos, como C++, C#, Visual Basic .NET y demases, es común utilizar una variable presente en todas las clases: el puntero this.

Este puntero (no confundir explícitamente con los punteros de C/C++; se debe interpretar mas bien como el “apuntador a”) hace referencia a la clase en si misma. Entender su funcionamiento es bastante simple, y en código se hace más evidente.

static public int sumardos(int valor)
{
    return valor + 2;
}

Hasta aquí nada muy nuevo. Una función sumardos que retorna un entero, que es un valor que se le entrega a esta función y se le suman dos unidades. Ahora, démosle contexto a este método (recordemos que en la jerga informática, función es una rutina que devuelve o no un valor. Un Método es una propiedad de los objetos que realiza una operación con el objeto o relativo a él).

public class operaciones{
    private int valor;

    public operaciones()
    {
      valor = 1;
    }

    static public int sumardos(int valor)
    {
      return valor + 2;
    }
}

Ahora, podemos apreciar que la clase también tiene un atributo (de nuevo, en la jerga informática, una variable es un elemento en el cual podemos almacenar datos, un atributo es una propiedad de los objetos relativos a estos) llamado valor.

Veamos como funciona el asunto.

operaciones obj = new operaciones();
Console.WriteLine("3 + 2 = " + obj.sumardos(3));

La consola imprime esto:

3 + 2 = 5

No hay problema. Se imprime el valor esperado, pero eso plantearía otra pregunta, ¿y como imprimo y/o utilizo el atributo valor y no solamente el parámetro valor dado al método?

Como se puede suponer, la solución y el objetivo de esta entrada es simplemente, referenciar a la misma clase (u objeto, según como se mire), con el puntero this.

public class operaciones{
    private int valor;

    public operaciones()
    {
      valor = 1;
    }

    static public int sumardos(int valor)
    {
      return this.valor + 2;
    }
}

Lo que, bajo la misma impresión dada anteriormente imprimirá:

3 + 2 = 3

Esto ocurre ya que ahora no tomo al parámetro valor, si no que al atributo valor, cuyo valor es 1.

Una de las buenas practicas de los lenguajes OOP cuando los programas comienzan a ser muy grandes, y trabajados entre varias personas, es la correcta utilización del puntero this donde corresponda; pues nadie sabe cuando un tercero podrá agregar atributos o parámetros con los mismos valores ya existentes en el ámbito privado o local, que harán que la aplicación deje de funcionar correctamente.

Notar que los nombres de variables repetidos no son marcados ni como advertencia ni como error, pues están en ámbitos diferentes.

Descomprimir fichero zip en Android

En ocasiones, necesitaremos descomprimir un archivo zip en Android para evitar la descarga de muchos archivos pequeños (como imágenes, o pequeños ficheros de texto), agrupándolos en uno solo.

Adjunto una clase heredada desde AsyncTask para mostrar un dialogo modal de espera mientras se ejecuta la descompresión. Esta funciona cargando en un buffer de 2MB para evitar una llamada constante al Garbage Collector mientras se escriben bytes individuales, lo que acelera INCREÍBLEMENTE el tiempo de descompresión.

package com.descompresor;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

class DescomprimeArchivos extends AsyncTask {

	ProgressDialog mProgresoDescompresion;
	String _Ubicacion_ZIP;
	String _Destino_Descompresion;
	boolean _Mantener_ZIP;

	/**
	 * Descomprime un archivo .ZIP
	 * @param ctx Contexto de la Aplicación Android
	 * @param Ubicacion_ZIP Ruta ABSOLUTA de un archivo .zip
	 * @param Destino_Descompresion Ruta ABSOLUTA del destino de la descompresión. Finalizar con /
	 * @param Mantener_ZIP Indica si se debe mantener el archivo ZIP despues de descomprimir
	 */
	public DescomprimeArchivos(Context ctx, String Ubicacion, String Destino, boolean Mantener)
	{
		mProgresoDescompresion = new ProgressDialog(ctx);
		mProgresoDescompresion.setTitle("Descomprimiendo...");
		mProgresoDescompresion.setMessage("Por favor espere...");
		mProgresoDescompresion.setIndeterminate(false);
		mProgresoDescompresion.setProgress(100);
		mProgresoDescompresion.setCancelable(true);
		mProgresoDescompresion.setProgressStyle(ProgressDialog.STYLE_SPINNER);

		_Ubicacion_ZIP = Ubicacion;
		_Destino_Descompresion = Destino;
		_Mantener_ZIP = Mantener;
	}

	@Override
	protected String doInBackground(String... params) {
		int size;
		byte[] buffer = new byte[2048];

		new File(_Destino_Descompresion).mkdirs(); //Crea la ruta de descompresion si no existe

		try {
			try {
				FileInputStream lector_archivo = new FileInputStream(_Ubicacion_ZIP);
				ZipInputStream lector_zip = new ZipInputStream(lector_archivo);
				ZipEntry item_zip = null;

				while ((item_zip = lector_zip.getNextEntry()) != null) {
					Log.v("Descompresor", "Descomprimiendo " + item_zip.getName());

					if (item_zip.isDirectory()) { //Si el elemento es un directorio, crearlo
						Crea_Carpetas(item_zip.getName(), _Destino_Descompresion);
					} else {
						FileOutputStream outStream = new FileOutputStream(
								_Destino_Descompresion + item_zip.getName());
						BufferedOutputStream bufferOut = new BufferedOutputStream(
								outStream, buffer.length);

						while ((size = lector_zip.read(buffer, 0, buffer.length)) != -1) {
							bufferOut.write(buffer, 0, size);
						}

						bufferOut.flush();
						bufferOut.close();
					}

				}
				lector_zip.close();
				lector_archivo.close();

				if(!_Mantener_ZIP)
					new File(_Ubicacion_ZIP).delete();

			} catch (Exception e) {
				Log.e("Descompresor", "Descomprimir", e);
			}
			mProgresoDescompresion.dismiss();
		} catch (Exception e) {
			Log.e("Error", e.getMessage());
		}
		return null;
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		mProgresoDescompresion.show();
	}

	@Override
	protected void onProgressUpdate(Integer... progress) {
		super.onProgressUpdate(progress);
		mProgresoDescompresion.setProgress(progress[0]);
	}

	private void Crea_Carpetas(String dir, String location) {
		File f = new File(location + dir);

		if (!f.isDirectory()) {
			f.mkdirs();
		}
	}

}

Instanciamos el objeto. Notar que grabaremos en el cache de la aplicación Android y no en la tarjeta SD o la memoria interna.

final DescomprimeArchivos descompresor = 
new DescomprimeArchivos(this, getApplicationContext().getCacheDir().toString() + 
"/archivo.zip", getApplicationContext().getCacheDir().toString() + "/descomprimir/", false);

Para utilizar esta clase, y basándonos en su derivación de AsyncTask podemos invocar al método público y estático excecute. Este método recibe parámetros de longitud variable (es decir, n argumentos), pero para este caso, no necesitamos ninguno. Como inicializamos con el contexto de Android previamente, podemos llamar a este método directamente desde el evento de un control. Para este ejemplo, invocamos el método directamente desde el evento OnClick de un Button.

Button btn_desc = (Button) findViewById(R.id.btn_desc);
		btn_desc.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				descompresor.execute();
			}
		});