如何让程序等待 java 中的方法
How to make a program wait for a method in java
我正在编写一个程序,returns 我是一个字符串数组列表。问题是,当我调用该方法时,列表尚未填充,所以我得到一个空列表。
我用一个线程试过了,但现在我在调用该方法时得到了一个 null
引用。顺便说一下,我必须实现一个异步任务,否则在尝试使用 InetAddress
.
时会出现异常
private class DeviceManager extends Thread {
private ArrayList<String> deviceList;
private String networkIP;
public DeviceManager(String networkIP) {
this.networkIP = networkIP;
}
public void run() {
getDeviceList();
}
public ArrayList<String> getDeviceList() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
deviceList = new ArrayList<String>();
InetAddress address;
Log.i("NetworkIPgetDeviceList", networkIP);
String deviceIP = networkIP;
for (int i = 0; i < 255; i++) {
address = InetAddress.getByName(deviceIP += "" + i);
if (address.isReachable(2000)) {
Log.i("Devicefound", deviceIP);
deviceList.add(deviceIP);
}
deviceIP = networkIP;
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute();
return deviceList;
}
public ArrayList<String> getList() {
return this.deviceList;
}
}
您得到的数组列表是空的,因为当您使用异步任务获取数组列表时,异步任务 doINBackground 方法在不同的线程上运行(意味着不在主线程上)。因此,当您的程序运行时,您的程序不会等待异步任务响应。
你可以这样解决...
在异步任务 class 和 return arraylist
中使用 onPostExecute 方法
@Override
protected void onPostExecute(Void result) {
//return array list here
getList();
}
希望对您有所帮助
你完全错了。 Thread
运行 在后台,AsyncTask
也是如此,所以基本上您是在后台执行后台任务 运行。 盗梦空间.
试试这个:
public class DeviceManager {
private ArrayList<String> deviceList;
private String networkIP;
private ConnectionCompleteListener listener;
public interface ConnectionCompleteListener {
void onSuccess();
void onFailure();
}
public void setConnectionCompleteListener(ConnectionCompleteListener listener) {
this.listener = listener;
}
public DeviceManager(String networkIP) {
this.networkIP = networkIP;
}
public void getDeviceList() {
new AsyncTask<Void, Void, Boolean>() {
@Override
protected void onPostExecute(Boolean result) {
if(result) listener.onSuccess();
else listener.onFailure();
}
@Override
protected Boolean doInBackground(Void... params) {
try {
deviceList = new ArrayList<String>();
InetAddress address;
Log.i("NetworkIPgetDeviceList", networkIP);
String deviceIP = networkIP;
for (int i = 0; i < 255; i++) {
address = InetAddress.getByName(deviceIP += "" + i);
if (address.isReachable(2000)) {
Log.i("Devicefound", deviceIP);
deviceList.add(deviceIP);
}
deviceIP = networkIP;
}
return true;
} catch (UnknownHostException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
return null;
}
}.execute();
}
public ArrayList<String> getList() {
return this.deviceList;
}
}
然后在你的另一个 class:
private class classname{
DeviceManager manager=new DeviceMnager(networkIp);
manger.setConnectionCompleteListener(new DeviceManager.ConnectionCompleteListener() {
@Override
public void onSuccess() {
// get your list here
manager.getList();
}
@Override
public void onFailure() {
// connection failed show error
}
});
}
首先,您不需要将 DeviceManager 设为线程,因为您在 getDeviceList 中 运行 的任务将在另一个新线程中启动。其次,您不应该在主线程(UI)上等待,因此等待回调是一种更好的机制。
如果你坚持使用相同的代码,试试这个..
public class DeviceManager extends Thread {
private ArrayList<String> deviceList;
private String networkIP;
private boolean dataAvailable;
public DeviceManager(String networkIP) {
this.networkIP = networkIP;
}
public void run() {
getDeviceList();
}
public ArrayList<String> getDeviceList() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
deviceList = new ArrayList<String>();
InetAddress address;
Log.i("NetworkIPgetDeviceList", networkIP);
String deviceIP = networkIP;
for (int i = 0; i < 255; i++) {
System.out.println("checking " + i);
address = InetAddress.getByName(deviceIP += "" + i);
if (address.isReachable(2000)) {
Log.i("Devicefound", deviceIP);
deviceList.add(deviceIP);
}
deviceIP = networkIP;
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
dataAvailable = true;
synchronized (DeviceManager.this) {
DeviceManager.this.notify();
}
return null;
}
}.execute();
return deviceList;
}
synchronized public ArrayList<String> getList() {
while (!dataAvailable) {
try {
wait();
} catch (InterruptedException e) {
}
}
return this.deviceList;
}
}
Artur 您在代码中所做的是启动一个线程来检索设备列表,然后启动另一个线程 (AsyncTask) 来实际创建设备列表。所以你同时在这里有三个线程 运行ning(假设你在 UIThread 中使用 DeviceManager class)。 getDeviceList()
返回 null 的原因是因为 AsyncTasks doInBackground
尚未 运行 收集您的设备列表,它可能正在等待机会得到安排。因此得出结论,您只需要一个线程(UIThread 除外),它可以是 Thread 或 AsyncTask(更可取,因为它提供更好的控制),因为 rusted brain 在他的回答中使用了。我更喜欢将 DeviceManager 设置为 AsyncTask(只是更简洁一点,如果设备管理器的唯一任务是检索设备列表)如下代码。
in AsyncTask doInBackground
运行s 在后台线程中(顾名思义)和 onPostExecute
运行s 在 UI 线程之后 doInBackground
class DeviceManager extends AsyncTask<String, Void, List<String>> {
private ConnectionCompleteListener listener;
public interface ConnectionCompleteListener {
void onSuccess(List<String> deviceList);
// if you need to know reason for failure you can add
// parameter to onFailure
void onFailure();
}
public DeviceManager(ConnectionCompleteListener listener) {
this.listener = listener;
}
@Override
protected List<String> doInBackground(String... params) {
List<String> deviceList = new ArrayList<>();
String networkIP = params[0];
try {
InetAddress address;
Log.i("NetworkIPgetDeviceList", networkIP);
String deviceIP = networkIP;
for (int i = 0; i < 255; i++) {
address = InetAddress.getByName(deviceIP += "" + i);
if (address.isReachable(2000)) {
Log.i("Devicefound", deviceIP);
deviceList.add(deviceIP);
}
deviceIP = networkIP;
}
} catch (IOException e) {
deviceList = null;
e.printStackTrace();
}
return deviceList;
}
@Override
protected void onPostExecute(List<String> deviceList) {
if (deviceList == null) {
this.listener.onFailure();
} else {
this.listener.onSuccess(deviceList);
}
}
}
所以在你的 activity 中你可以调用
new DeviceManager(new DeviceManager.ConnectionCompleteListener
() {
@Override
public void onSuccess(List<String> deviceList) {
}
@Override
public void onFailure() {
}
}).execute("YOUR_NETWORK_IP");
我正在编写一个程序,returns 我是一个字符串数组列表。问题是,当我调用该方法时,列表尚未填充,所以我得到一个空列表。
我用一个线程试过了,但现在我在调用该方法时得到了一个 null
引用。顺便说一下,我必须实现一个异步任务,否则在尝试使用 InetAddress
.
private class DeviceManager extends Thread {
private ArrayList<String> deviceList;
private String networkIP;
public DeviceManager(String networkIP) {
this.networkIP = networkIP;
}
public void run() {
getDeviceList();
}
public ArrayList<String> getDeviceList() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
deviceList = new ArrayList<String>();
InetAddress address;
Log.i("NetworkIPgetDeviceList", networkIP);
String deviceIP = networkIP;
for (int i = 0; i < 255; i++) {
address = InetAddress.getByName(deviceIP += "" + i);
if (address.isReachable(2000)) {
Log.i("Devicefound", deviceIP);
deviceList.add(deviceIP);
}
deviceIP = networkIP;
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute();
return deviceList;
}
public ArrayList<String> getList() {
return this.deviceList;
}
}
您得到的数组列表是空的,因为当您使用异步任务获取数组列表时,异步任务 doINBackground 方法在不同的线程上运行(意味着不在主线程上)。因此,当您的程序运行时,您的程序不会等待异步任务响应。
你可以这样解决... 在异步任务 class 和 return arraylist
中使用 onPostExecute 方法@Override
protected void onPostExecute(Void result) {
//return array list here
getList();
}
希望对您有所帮助
你完全错了。 Thread
运行 在后台,AsyncTask
也是如此,所以基本上您是在后台执行后台任务 运行。 盗梦空间.
试试这个:
public class DeviceManager {
private ArrayList<String> deviceList;
private String networkIP;
private ConnectionCompleteListener listener;
public interface ConnectionCompleteListener {
void onSuccess();
void onFailure();
}
public void setConnectionCompleteListener(ConnectionCompleteListener listener) {
this.listener = listener;
}
public DeviceManager(String networkIP) {
this.networkIP = networkIP;
}
public void getDeviceList() {
new AsyncTask<Void, Void, Boolean>() {
@Override
protected void onPostExecute(Boolean result) {
if(result) listener.onSuccess();
else listener.onFailure();
}
@Override
protected Boolean doInBackground(Void... params) {
try {
deviceList = new ArrayList<String>();
InetAddress address;
Log.i("NetworkIPgetDeviceList", networkIP);
String deviceIP = networkIP;
for (int i = 0; i < 255; i++) {
address = InetAddress.getByName(deviceIP += "" + i);
if (address.isReachable(2000)) {
Log.i("Devicefound", deviceIP);
deviceList.add(deviceIP);
}
deviceIP = networkIP;
}
return true;
} catch (UnknownHostException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
return null;
}
}.execute();
}
public ArrayList<String> getList() {
return this.deviceList;
}
}
然后在你的另一个 class:
private class classname{
DeviceManager manager=new DeviceMnager(networkIp);
manger.setConnectionCompleteListener(new DeviceManager.ConnectionCompleteListener() {
@Override
public void onSuccess() {
// get your list here
manager.getList();
}
@Override
public void onFailure() {
// connection failed show error
}
});
}
首先,您不需要将 DeviceManager 设为线程,因为您在 getDeviceList 中 运行 的任务将在另一个新线程中启动。其次,您不应该在主线程(UI)上等待,因此等待回调是一种更好的机制。
如果你坚持使用相同的代码,试试这个..
public class DeviceManager extends Thread {
private ArrayList<String> deviceList;
private String networkIP;
private boolean dataAvailable;
public DeviceManager(String networkIP) {
this.networkIP = networkIP;
}
public void run() {
getDeviceList();
}
public ArrayList<String> getDeviceList() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
deviceList = new ArrayList<String>();
InetAddress address;
Log.i("NetworkIPgetDeviceList", networkIP);
String deviceIP = networkIP;
for (int i = 0; i < 255; i++) {
System.out.println("checking " + i);
address = InetAddress.getByName(deviceIP += "" + i);
if (address.isReachable(2000)) {
Log.i("Devicefound", deviceIP);
deviceList.add(deviceIP);
}
deviceIP = networkIP;
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
dataAvailable = true;
synchronized (DeviceManager.this) {
DeviceManager.this.notify();
}
return null;
}
}.execute();
return deviceList;
}
synchronized public ArrayList<String> getList() {
while (!dataAvailable) {
try {
wait();
} catch (InterruptedException e) {
}
}
return this.deviceList;
}
}
Artur 您在代码中所做的是启动一个线程来检索设备列表,然后启动另一个线程 (AsyncTask) 来实际创建设备列表。所以你同时在这里有三个线程 运行ning(假设你在 UIThread 中使用 DeviceManager class)。 getDeviceList()
返回 null 的原因是因为 AsyncTasks doInBackground
尚未 运行 收集您的设备列表,它可能正在等待机会得到安排。因此得出结论,您只需要一个线程(UIThread 除外),它可以是 Thread 或 AsyncTask(更可取,因为它提供更好的控制),因为 rusted brain 在他的回答中使用了。我更喜欢将 DeviceManager 设置为 AsyncTask(只是更简洁一点,如果设备管理器的唯一任务是检索设备列表)如下代码。
in AsyncTask doInBackground
运行s 在后台线程中(顾名思义)和 onPostExecute
运行s 在 UI 线程之后 doInBackground
class DeviceManager extends AsyncTask<String, Void, List<String>> {
private ConnectionCompleteListener listener;
public interface ConnectionCompleteListener {
void onSuccess(List<String> deviceList);
// if you need to know reason for failure you can add
// parameter to onFailure
void onFailure();
}
public DeviceManager(ConnectionCompleteListener listener) {
this.listener = listener;
}
@Override
protected List<String> doInBackground(String... params) {
List<String> deviceList = new ArrayList<>();
String networkIP = params[0];
try {
InetAddress address;
Log.i("NetworkIPgetDeviceList", networkIP);
String deviceIP = networkIP;
for (int i = 0; i < 255; i++) {
address = InetAddress.getByName(deviceIP += "" + i);
if (address.isReachable(2000)) {
Log.i("Devicefound", deviceIP);
deviceList.add(deviceIP);
}
deviceIP = networkIP;
}
} catch (IOException e) {
deviceList = null;
e.printStackTrace();
}
return deviceList;
}
@Override
protected void onPostExecute(List<String> deviceList) {
if (deviceList == null) {
this.listener.onFailure();
} else {
this.listener.onSuccess(deviceList);
}
}
}
所以在你的 activity 中你可以调用
new DeviceManager(new DeviceManager.ConnectionCompleteListener
() {
@Override
public void onSuccess(List<String> deviceList) {
}
@Override
public void onFailure() {
}
}).execute("YOUR_NETWORK_IP");