我在我的应用中使用Object.freeze()。 我做一个异步请求来获取这样的对象:
package testbroadcastudp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
/**
* @since 03-05-2017
* @author jsanchez
*/
public class UDPBroadcastToLantronixDevices {
public static void main(String[] args){
//Port 30718 for sent at Lantronix devices
try (DatagramSocket serverSocket = new DatagramSocket(30718))
{//30718 50000
byte[] queryMsg = new byte[4];
queryMsg[0] = (byte)0x00;
queryMsg[1] = (byte)0x00;
queryMsg[2] = (byte)0x00;
queryMsg[3] = (byte)0xF6;//Dec 246
String testByte = new String(queryMsg,StandardCharsets.ISO_8859_1);
serverSocket.setBroadcast(true);
DatagramPacket datagramPacket = new DatagramPacket(
queryMsg,
queryMsg.length,
InetAddress.getByName("192.168.1.255"),//192.168.1.201
30718
);
//Send broadcast
serverSocket.send(datagramPacket);
//Close Broadcast socket to close the 30718 port.
serverSocket.close();
//Start the listening from the server
receive();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
static void receive(){
//Port 30718 for listen Lantronix devices
try (DatagramSocket clientSocket = new DatagramSocket(30718)) {
byte[] buffer = new byte[4];
// Set a timeout of 3000 ms to listen in the server side
clientSocket.setSoTimeout(3000);
while (true) {
DatagramPacket datagramPacket = new DatagramPacket(buffer, 0, buffer.length);
/**
* The receive method will wait for 3000 ms for data.
* After that, the server will throw a timeout exception.
*/
clientSocket.receive(datagramPacket);
System.out.println("Listen on " + datagramPacket.getAddress() + " from " + datagramPacket.getData().toString() + " port " + datagramPacket.getPort());
String receivedMessage = new String(datagramPacket.getData());
//Decode to get the 0xF7 or '÷' in the byte[4] for a Lantronix Devices in the LAN
receivedMessage = new String(datagramPacket.getData(), StandardCharsets.ISO_8859_1);
System.out.println(receivedMessage);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("Timeout. Client is closing.");
}
}
}
听众类:
public static void getMissions(final List<StatutMission> listStatus, final SListener<List<RMission>> listener) {
final String[] statesCode = new String[listStatus.size()];
for (int i = 0; i < listStatus.size(); i++) {
statesCode[i] = listStatus.get(i).getStateCode();
}
final RealmResults<RMission> results = Realm.getDefaultInstance().where(RMission.class).in("state", statesCode).findAllAsync();
results.addChangeListener(new RealmChangeListener<RealmResults<RMission>>() {
@Override
public void onChange(RealmResults<RMission> element) {
Log.d(TAG, element.size() + " mission(s) found in database with states " + StringUtils.arrayToString(statesCode, ","));
listener.onResponse(Realm.getDefaultInstance().copyFromRealm(element));
results.removeChangeListener(this);
}
});
}
}
我在多台设备上测试了我的代码,但只在一台设备(三星平板电脑)上测试了这个问题。
问题代码:
public interface SListener<T> {
void onResponse(@Nullable T result);
有人可以帮我解决这个问题吗?
提前致谢。
答案 0 :(得分:2)
1。)Realm.getDefaultInstance().where(...
和Realm.getDefaultInstance().copyFromRealm(...
您正在打开永远无法关闭的Realm实例,请阅读the docs
2。)你没有保留RealmResults作为字段引用,因此终结器会在评估异步查询之前销毁它,因此不会调用回调,阅读文档here和here
来自 javadoc:
注册更改侦听器不会阻止底层RealmResults被垃圾回收。 如果RealmResults被垃圾收集,则更改侦听器将停止被触发。为避免这种情况,请尽可能长时间保持强有力的参考,例如在类变量中。
public class MyActivity extends Activity { private RealmResults<Person> results; // Strong reference to keep listeners alive @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); results = realm.where(Person.class).findAllAsync(); results.addChangeListener(new RealmChangeListener<RealmResults<Person>>() { @Override public void onChange(RealmResults<Person> persons) { // React to change } }); } // remove change listeners, and close Realm in onDestroy() }
3.。)如果你 复制懒惰评估的RealmResults EEGERLY中的每一个懒惰评估元素,那么对于异步评估查询的所有麻烦都是没有意义的 ,所以你应该重新评估你的逻辑,特别是在你阅读the relevant docs on how Realm queries work之后。
所有提取(包括查询)在Realm中都是惰性的,数据永远不会被复制。
由于数据永远不会被复制,因此您没有理由使用copyFromRealm()
。