java - tesis - ejemplo de redaccion de resultados
¿Hay alguna manera de tomar una discusión en un método invocable? (6)
Añadiendo a la respuesta de Jarle, en caso de que cree Callable
como instancia de clase anónima, puede usar el campo final
fuera de la clase anónima para pasar datos a la instancia:
final int arg = 64;
executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return arg * 2;
}
});
He creado un fragmento de código que toma una dirección IP (del método principal en otra clase) y luego recorre un rango de direcciones IP haciendo ping a cada una de ellas a medida que avanza. Tengo una interfaz gráfica de usuario en esto y estaba fallando (de ahí que haya hecho el multihilo. Mi problema es que ya no puedo tomar como argumento la dirección IP en mi código de ping. He buscado en todas partes para esto y parece que no se puede encontrar una manera de eludir esto. ¿Hay alguna manera para que un método invocable tome argumentos? ¿De no haber otra forma de lograr lo que estoy tratando de hacer?
muestra de mi código:
public class doPing implements Callable<String>{
public String call() throws Exception{
String pingOutput = null;
//gets IP address and places into new IP object
InetAddress IPAddress = InetAddress.getByName(IPtoPing);
//finds if IP is reachable or not. a timeout timer of 3000 milliseconds is set.
//Results can vary depending on permissions so cmd method of doing this has also been added as backup
boolean reachable = IPAddress.isReachable(1400);
if (reachable){
pingOutput = IPtoPing + " is reachable./n";
}else{
//runs ping command once on the IP address in CMD
Process ping = Runtime.getRuntime().exec("ping " + IPtoPing + " -n 1 -w 300");
//reads input from command line
BufferedReader in = new BufferedReader(new InputStreamReader(ping.getInputStream()));
String line;
int lineCount = 0;
while ((line = in.readLine()) != null) {
//increase line count to find part of command prompt output that we want
lineCount++;
//when line count is 3 print result
if (lineCount == 3){
pingOutput = "Ping to " + IPtoPing + ": " + line + "/n";
}
}
}
return pingOutput;
}
}
IPtoPing solía ser el argumento que se tomó.
Coloque algunos campos ( final
) en su clase doPing
y un constructor que los inicialice, luego pase los valores que desea usar en call()
al constructor de doPing
:
public class doPing implements Callable<String> {
private final String ipToPing;
public doPing(String ip) {
this.ipToPing = ip;
}
public String call() {
// use ipToPing
}
}
Cuando cree la clase doPing (debe ser una letra capial en el nombre de la clase), envíe la dirección IP en el constructor. Use esta dirección IP en el método de llamada.
Debes definir una propiedad como ipAddress
y su método de acceso. y pasando su valor en constructor
o por método setter
. En la clase doPing
, use la propiedad ipAddress
.
class DoPing/* In java all classes start with capital letter */implements Callable<String>
{
private String ipAddress;
public String getIpAddress()
{
return ipAddress;
}
public void setIpAddress(String ipAddress)
{
this.ipAddress = ipAddress;
}
/*
* Counstructor
*/
public DoPing(String ipAddress )
{
this.ipAddress = ipAddress;
}
@Override
public String call() throws Exception
{
// your logic
}
}
No puede pasar argumentos a call()
porque la firma del método no lo permite, pero aquí hay al menos una forma de solucionarlo mediante
- definiendo una clase abstracta que envuelve / implementa
Callable
y - implementar un setter para "inyectar" un resultado en
call()
Definir una clase abstracta:
import java.util.concurrent.Callable;
public abstract class Callback<T> implements Callable<Void> {
T result;
void setResult (T result) {
this.result = result;
}
public abstract Void call ();
}
Defina el método que debe activar la devolución de llamada:
public void iWillFireTheCallback (Callback callback) {
// You could also specify the signature like so:
// Callback<Type of result> callback
// make some information ("the result")
// available to the callback function:
callback.setResult("Some result");
// fire the callback:
callback.call();
}
En el lugar donde deseas llamar a iWillFireTheCallback
:
Defina la función de devolución de llamada (incluso posible dentro de métodos):
class MyCallback extends Callback {
@Override
public Void call () {
// this is the actual callback function
// the result variable is available right away:
Log.d("Callback", "The result is: " + result);
return null;
}
}
Y luego llame a iWillFireTheCallback
mientras pasa la devolución de llamada:
iWillFireTheCallback(new MyCallback());
No puede pasarlo como el argumento para call()
porque la firma del método no lo permite.
Sin embargo, puede pasarlo como un argumento de constructor; p.ej
public class DoPing implements Callable<String>{
private final String ipToPing;
public DoPing(String ipToPing) {
this.ipToPing = ipToPing;
}
public String call() throws SomeException {
InetAddress ipAddress = InetAddress.getByName(ipToPing);
....
}
}
(¡He corregido un par de atroces violaciones de estilo de código!)
Alternativamente, usted podría:
declarar DoPing como clase interna y hacer que se refiera a una
final ipToPing
en el ámbito adjunto, oagregue un
setIpToPing(String ipToPing)
.
(El último permite DoPing
un objeto DoPing
, pero la desventaja es que tendrá que sincronizarse para acceder a él de forma segura).