J'ai créé un morceau de code qui prend une adresse IP (à partir de la méthode principale dans une autre classe), puis fait une boucle à travers une plage d'adresses IP qui cinglent chacune au fur et à mesure. J'ai une interface graphique à ce sujet et il plantait (d'où la raison pour laquelle j'ai fait le multithreading. Mon problème est que je ne peux plus prendre l'adresse IP comme argument dans mon code ping comme appelable. J'ai cherché partout pour cela et je ne peux pas trouver un moyen de contourner ce problème. Existe-t-il un moyen pour une méthode appelable de prendre des arguments? Sinon, existe-t-il un autre moyen d'accomplir ce que j'essaie de faire?
exemple de mon code:
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 était l'argument utilisé.
Vous ne pouvez pas le passer comme argument à call()
car la signature de la méthode ne le permet pas.
Cependant, vous pouvez le passer comme argument constructeur; par exemple.
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);
....
}
}
(J'ai corrigé quelques violations flagrantes du style de code !!)
Vous pouvez également:
déclarer DoPing en tant que classe interne et le faire référence à un final ipToPing
dans la portée englobante, ou
ajoutez une méthode setIpToPing(String ipToPing)
.
(Le dernier permet de réutiliser un objet DoPing
, mais l'inconvénient est que vous devrez vous synchroniser pour y accéder en toute sécurité.)
Ajout à la réponse de Jarle - dans le cas où vous créez Callable
comme instance de classe anonyme, vous pouvez utiliser le champ final
en dehors de la classe anonyme pour passer des données dans l'instance:
final int arg = 64;
executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return arg * 2;
}
});
Lorsque vous créez la classe doPing (qui doit être en majuscule dans le nom de la classe), envoyez l'adresse IP dans le constructeur. Utilisez cette adresse IP dans la méthode d'appel.
Vous ne pouvez pas passer d'arguments à call()
parce que la signature de la méthode ne le permet pas mais voici au moins une façon de contourner cela en
Callable
etcall()
Définissez une classe abstraite:
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 ();
}
Définissez la méthode qui doit déclencher le rappel:
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();
}
À l'endroit où vous souhaitez appeler iWillFireTheCallback
:
Définissez la fonction de rappel (même possible à l'intérieur des méthodes):
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;
}
}
Et puis appelez iWillFireTheCallback
en passant le rappel:
iWillFireTheCallback(new MyCallback());
Mettez quelques champs (final
) dans votre classe doPing
et un constructeur qui les initialise, puis passez les valeurs que vous souhaitez utiliser dans call()
au constructeur de doPing
:
public class doPing implements Callable<String> {
private final String ipToPing;
public doPing(String ip) {
this.ipToPing = ip;
}
public String call() {
// use ipToPing
}
}
Vous devez définir une propriété telle que ipAddress
et sa méthode d'accesseur. et en passant sa valeur dans constructor
ou par la méthode setter
. Dans la classe doPing
, utilisez la propriété 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
}
}