martes, 11 de marzo de 2008

Acceso a archivos y threads

Corriendo un ejemplo de escritura de archivos en Sun Java Wireless Toolkit sucedía que la aplicación se colgaba al momento de abrir el archivo.

En la consola se mostraba este mensaje:
Warning: To avoid potential deadlock, operations that may block, such as
networking, should be performed in a different thread than the
commandAction() handler.


El mismo problema aparecía en el ejemplo de lectura de un directorio que estaba escribiendo. En ambos casos la aplicación se colgaba al llamar a Connector.open.

La advertencia en cuestión quedaría traducida a:
"Para evitar posibles puntos muertos, las operaciones que pueden bloquear, como conexiones de red, deben ser ejecutadas en un hilo (thread) diferente que el administrador de commandAction()"

El "commandAction() handler" sería la clase que especificamos para manejar la interacción con el usuario mediante el método setCommandListener.

Como un conexión de red o un acceso a un archivo puede dejar inutilizable la interfaz de usuario, debe correrse en un thread separado.

Una muy buena explicación de esto puede encontrarse en:
Networking, User Experience, and Threads

En cuanto a la solución de este error en particular fue cambiar este código:


public void ShowContents() {
listContents = new List("Contenidos de " + currentRoot, Choice.EXCLUSIVE);

try{

FileConnection myFc = (FileConnection)
Connector.open("file:///" + currentRoot);
Enumeration fileEnum = myFc.list("*", false);
while(fileEnum.hasMoreElements()) {
String fileName = (String) fileEnum.nextElement();
listContents.append(fileName, null);
}
} catch (Throwable th) {
System.out.println(th.toString());
}

listContents.addCommand(cmExit);
listContents.setCommandListener(this);
Display.getDisplay(this).setCurrent(listContents);
}

Por este:

public void ShowContents() {
listContents = new List("Contenidos de " + currentRoot, Choice.EXCLUSIVE);
Display.getDisplay(this).setCurrent(WaitForm);
Thread t = new Thread() {
public void run() {
try{

FileConnection myFc = (FileConnection)
Connector.open("file:///" + currentRoot);
Enumeration fileEnum = myFc.list("*", false);
while(fileEnum.hasMoreElements()) {
String fileName = (String) fileEnum.nextElement();
listContents.append(fileName, null);
}
} catch (Throwable th) {
System.out.println(th.toString());
}
}
};
t.start();
listContents.addCommand(cmExit);
listContents.setCommandListener(this);
Display.getDisplay(this).setCurrent(listContents);

}

De acuerdo a lo explicado en el artículo citado.

Para ver un ejemplo de como listar roots y escribir archivos ir a:
Leer y escribir archivos en J2ME

4 comentarios:

Anónimo dijo...

por favor ayduame me sale este error al conectarme con un webservice
Warning: To avoid potential deadlock, operations that may block, such as
networking, should be performed in a different thread than the
commandAction() handler.

que puedo hacer
mi correo es mquirozm1984@hotmail.com

Guish dijo...

mirá el ejemplo posteado, lo que tenés que hacer es identificar en tu código cuales son las líneas que provocan ese error y ejecutarlas dentro de un thread como se ve en negritas en el segundo fragmento de código del ejemplo.

Miguel dijo...

Gracias amigo, me ha sido muy util esta informacion

Carlos dijo...

Que tal amigo, ya tiene ratos este tu post, pero solo pase a agradecerte, me salvaste la vida con esas 3 lineas :-)

Gracias