IPアドレス(別のクラスのメインメソッドから)を取得し、IPアドレスの範囲をループし、各IPアドレスにpingを実行するコードを作成しました。私はこれにGUIフロントエンドを持っていますが、クラッシュしていました(そのためマルチスレッドを実行した理由です。私の問題は、呼び出し可能としてpingコードの引数としてIPアドレスを取ることができなくなりました。呼び出し可能なメソッドが引数を取る方法はありますか?そうでない場合、私がやろうとしていることを達成する他の方法はありますか?
私のコードのサンプル:
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は、以前は引数として使用されていました。
メソッドのシグネチャでは許可されていないため、call()
の引数として渡すことはできません。
ただし、コンストラクター引数として渡すことができます。例えば.
_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);
....
}
}
_
(私はいくつかのひどいコードスタイル違反を修正しました!!)
または、次のこともできます。
doPingを内部クラスとして宣言し、それを囲むスコープ内の_final ipToPing
_を参照させる、または
setIpToPing(String ipToPing)
メソッドを追加します。
(最後はDoPing
オブジェクトの再利用を許可しますが、欠点は、スレッドセーフでアクセスするために同期する必要があることです。)
Jarleの答えに追加-Callable
を匿名クラスのインスタンスとして作成する場合、匿名クラスの外部でfinal
フィールドを使用して、インスタンスにデータを渡すことができます。
final int arg = 64;
executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return arg * 2;
}
});
DoPing-classを作成するとき(クラス名の大文字でなければなりません)、コンストラクターでip-addressを送信します。 call-methodでこのIPアドレスを使用します。
メソッドのシグネチャでは許可されていないため、引数をcall()
に渡すことはできませんが、少なくとも次の方法で回避できます。
Callable
をラップ/実装する抽象クラスを定義し、call()
に「注入」するセッターを実装する抽象クラスの定義:
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 ();
}
コールバックを起動するメソッドを定義します:
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();
}
iWillFireTheCallback
:を呼び出したい場所で
コールバック関数を定義します(メソッド内でも可能):
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;
}
}
そして、コールバックを渡しながらiWillFireTheCallback
を呼び出します:
iWillFireTheCallback(new MyCallback());
final
クラスにいくつかの(doPing
)フィールドとそれらを初期化するコンストラクターを配置し、call()
で使用する値をdoPing
のコンストラクターに渡します。
public class doPing implements Callable<String> {
private final String ipToPing;
public doPing(String ip) {
this.ipToPing = ip;
}
public String call() {
// use ipToPing
}
}
ipAddress
などのプロパティとそのアクセサメソッドを定義する必要があります。 constructor
またはsetter
メソッドで値を渡します。 doPing
クラスでは、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
}
}