我尝试用 android.socket.io 编写一个简单的聊天。
我下面的代码有效,但我不确定是否需要静态方法,因为对于 ListView 字段和 MyBaseAdapter 类,我收到以下消息:
Do not place Android context classes in static fields; this is a memory leak
如果我将其更改为非静态,我会收到以下错误消息:
MyBaseAdapter.notifyDataSetChanged()' on a null object reference
下面是我的代码:
package com.example.seadog.fb_dialog;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import io.socket.emitter.Emitter;
public class MainActivity extends Activity implements Emitter.Listener {
private static ArrayList arrayList = new ArrayList();
private static ListView listView;
private static MyBaseAdapter adapter;
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SocketIo socketIo = new SocketIo(this);
if(socketIo.getSocket()==null) {
socketIo.Connection();
}
listView = (ListView) findViewById(R.id.listView);
adapter = new MyBaseAdapter(this, arrayList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent newActivity = new Intent(MainActivity.this, Conversation.class);
startActivity(newActivity);
}
});
}
@Override
public void call(Object... args) {
adapter.notifyDataSetChanged();
}
}
下面是我的 SocketIo 类代码:
package com.example.seadog.fb_dialog;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.URISyntaxException;
import io.socket.client.Ack;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
public class SocketIo {
private static Socket mSocket = null;
private Emitter.Listener messageListener;
private String API_BASE_URL = "http://10.0.2.2:3030";
private Integer id = 654864; // Website ID
private Integer userId = 6522; // UserID
private String jwt;
public SocketIo(Emitter.Listener messageListener) {
this.messageListener = messageListener;
}
public void Connection() {
try {
mSocket = IO.socket(API_BASE_URL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
/*
* Join to default a room after connect
*/
@Override
public void call(Object... args) {
// create json object and join to room (Website ID)
// ...more code, not important here
}
}).on("jwt", new Emitter.Listener() {
/*
* Get a token and find all active conversations
*/
@Override
public void call(Object... args) {
// get a token as args
jwt = args[0].toString();
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("token", jwt);
} catch (JSONException e) {
e.printStackTrace();
}
// find active conversations
mSocket.emit("messages::find", jsonObject, new Ack() {
@Override
public void call(Object... args) {
String response = args[args.length - 1].toString();
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = jsonArray.length() - 1; i >= 0; i--) {
// create JSON object and add to arrayList
mainActivity.setArrayList(ld);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}).on("message", new Emitter.Listener() {
/*
* Message Listener
*/
@Override
public void call(Object... args) {
String message = null;
try {
JSONObject object = (JSONObject) args[0];
// Create here JSON Object and add to JSON Array
mainActivity.setArrayList(ld);
} catch (JSONException e) {
e.printStackTrace();
}
String finalMessage = message;
//mainActivity.notifyDataSetChanged();
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
}
});
mSocket.connect();
}
public Integer getId(){
return id;
}
public Socket getSocket(){
return mSocket;
}
}
最佳答案
将您的代码分解为 MVP 模式。 编写一个与您的 Activity 直接相关的 Presenter。 Presenter 用于包装对 I/O、数据库等所需的库、框架等的调用。
演示者可以填充界面
void onData(ListData data);
不要直接调用您的 Activity ,而是调用您的演示者。他将缓存您的数据,根据您的 Activity 需要对其进行转换,并且我们的 Activity 可能有一个功能,通过类似的接口(interface)公开
void displayListItems(List<ListDataViewModel> viewModels);
如果 Activity/Presenter 将关闭,请尝试实现一个存储库,即将数据存储到本地数据库,以便您可以恢复它们。
关于java - 如何使用 Socket.io 从另一个类正确刷新 ListView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44160222/