2012-04-03 20 views
30

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 de que un método invocable tome argumentos? Si no, ¿hay alguna otra forma de lograr lo que intento?¿Hay alguna manera de tomar un argumento en un método invocable?

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 de que fue tomado

Respuesta

37

No se puede pasar como argumento a 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 violaciónes código de estilo flagrantes !!)

Como alternativa, puede:

  • dopaje declarar como una clase interna y hacer que se refiere a una final ipToPing en el alcance adjunto, o

  • agregue un método setIpToPing(String ipToPing).

(El último permite un objeto DoPing para ser reutilizado, pero el inconveniente es que se necesita para sincronizar para acceder a ella de hilo de manera segura.)

+0

así que .... esto no funcionará si pasa la invocable como parámetro a otra función que trata de repetir Callable frente a una serie de argumentos que se aprobó ... – Michael

+0

¿Es esto una declaración o una pregunta? De cualquier manera, no puedo entender lo que estás diciendo/preguntando. –

5

al crear la clase dopaje (debe ser carta captial en nombre de la clase), enviar º e dirección IP en el constructor. Use esta dirección IP en el método de llamada.

4

Ponga un poco (final) campos de la clase doPing, y un constructor que inicializa ellos, a continuación, pasar los valores que desea utilizar 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 
    } 
} 
6

Agregando a la respuesta de Jarle - en caso de que se crea Callable como instancia de clase anónima, puede utilizar final campo fuera de la clase anónima para pasar datos en la instancia:

final int arg = 64; 
    executor.submit(new Callable<Integer>() { 
     public Integer call() throws Exception { 
      return arg * 2; 
     } 
    }); 
1

usted tiene que defien una propiedad como ipAddress y su descriptor de acceso se reunió capacho. y pasando su valor en constructor o por el método setter. En doPing clase 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 
    } 
} 
2

No se puede pasar argumentos a call() debido a la firma del método no lo permite, pero aquí es por lo menos una manera de resolver esto

  1. definir una clase abstracta que envuelve/aperos Callable y
  2. la implementación de un colocador "inyectar" 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(); 
} 

Definir el método que se debe disparar 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 desea llamar 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 llamar iWillFireTheCallback mientras que pasa en la devolución de llamada:

iWillFireTheCallback(new MyCallback()); 
Cuestiones relacionadas