我最近开始学习android开发(我也是java的新手),我目前正在开发聊天/信使应用程序
正如标题所说,我面临的问题是,除非滚动,否则显示消息的列表视图不会在设备上更新,但它在虚拟机上运行正常。到目前为止,我只在LG Optimus l5 II
进行了测试,但无论如何我还需要解决此问题。
我认为它与多线程有关,因为直到我添加了一些新线程才会发生这种情况,所以我认为listview,android manifest和rest的适配器设置正确。如果它有帮助我可以添加它们。
我添加的2个主题可能会导致此问题:
我测试仅在第二个线程打开时运行,问题仍然存在。
我想指定这是我第一次尝试这样的东西(服务器 - 客户端,多线程,java,android(我还在大学,他们不会教我们这些东西)),我之前没有关于如何在服务器和客户端之间建立通信的文档。这是我能想到的最有效的方式。
这是onCreate
:
StartConnectingRoutine(); // so you know where it all starts
及其代码:
private void StartConnectingRoutine()
{
Thread t = new Thread()
{
@Override
public void run()
{
while(true)
{
if(!connected)
{
if( connect != null)
{
if(!connect.isAlive())
{
ConnectListener();
}
}
else
{
ConnectListener();
}
}
try {
sleep(CONNECTION_CHECK_TIME_MS); // this is set to 10000 (10 seconds)
} catch (InterruptedException e) {
Log.e("Intrerrupted", e.toString());
}
}
}
};
t.start();
}
和connectListener()
:
private void ConnectListener()
{
Log.d("Connecting", "Connecting...");
connect = new Thread()
{
JSONObject info = new JSONObject();
String receivedMessage;
@Override
public void run()
{
try {
info.put("Name", user.GetName());
info.put("PORT", MY_PORT);
info.put("IPv4", getIpAddress());
} catch (JSONException e1) {
Log.e("JSON", "JSON error: " + e1.toString());
}
try
{
ServerSocket = new Socket(SERVER_IP, SERVER_PORT);
dis = new DataInputStream(ServerSocket.getInputStream());
dos = new DataOutputStream(ServerSocket.getOutputStream());
dos.writeUTF(info.toString());
dos.flush();
String response = dis.readUTF();
if(response.equals("connected"))
{
Log.d("Connect", "Connected!");
connected = true;
}
else
Log.d("Connect", "Failed to connect!");
while(connected)
{
receivedMessage = dis.readUTF();
DisplayNewMessage(new MMessage(receivedMessage, MMessage.MessageType.Received));
}
}catch(SocketException e)
{
try {
if(connected)
{
ServerSocket.close();
dis.close();
dos.close();
connected = false;
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
catch(Exception e)
{
Log.d("Connect", "Failed to connect");
Log.e("Connect", e.toString());
connected = false;
}
}
};
connect.start();
}
固定
重新连接线程(我也试过使用asyncTask,但它不会打开另一个asyncTask,即使我试图从onProgressUpdate()打开它 - 它应该能够运行ui线程组件):
private void startConnectingRoutine()
{
Thread t = new Thread()
{
@Override
public void run()
{
Log.d("ConnectingRoutine", "Started connecting routine.");
while(true)
{
if(!connected)
{
startListener();
}
try {
sleep(CONNECTION_CHECK_TIME_MS);
} catch (InterruptedException e) {
Log.e("Intrerrupted", e.toString());
}
}
}
};
t.start();
}
监听线程:
private void startListener()
{
new Listener().execute();
}
。
private class Listener extends AsyncTask<Long, String, Long>
{
@Override
protected Long doInBackground(Long... params) {
Log.d("Connecting...", "Connecting...");
JSONObject info = new JSONObject();
String receivedMessage;
try {
info.put("Name", user.GetName());
info.put("PORT", MY_PORT);
info.put("IPv4", getIpAddress());
} catch (JSONException e1) {
Log.e("JSON", "JSON error: " + e1.toString());
}
try
{
serverSocket = new Socket(SERVER_IP, SERVER_PORT);
dis = new DataInputStream(serverSocket.getInputStream());
dos = new DataOutputStream(serverSocket.getOutputStream());
dos.writeUTF(info.toString());
dos.flush();
String response = dis.readUTF();
if(response.equals("connected"))
{
Log.d("Connect", "Connected!");
connected = true;
}
else
Log.d("Connect", "Failed to connect!");
while(connected)
{
receivedMessage = dis.readUTF();
publishProgress(receivedMessage);
}
}
catch(Exception e)
{
Log.d("Connect", "Failed to connect");
Log.e("Connect", e.toString());
return null;
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
displayNewMessage(new MMessage(values[0], MMessage.MessageType.Received));
}
@Override
protected void onPostExecute(Long result) {
super.onPostExecute(result);
connected = false;
try{
if(serverSocket != null)
serverSocket.close();
if(dis != null)
dis.close();
if(dos != null)
dos.close();
}catch(Exception e)
{
Log.e("Listener", "There was a problem closing the connection: " + e.toString());
}
}
}
答案 0 :(得分:0)
这里可能存在多种问题,但跳出来的有两个:
DisplayNewMessage()
。我建议您在后台查看更好的机制来执行任务,而不仅仅是创建一个Thread。使用AsyncTasks将是一个良好的开端,但您需要特别注意处理配置更改之间的任务(例如旋转设备)。
此外,当您将方法名称大写时,您的代码很难阅读。这违反了Java代码约定。您可以通过整齐地格式化代码(一个好的IDE帮助它)并学习遵循惯例来使自己更容易!