为什么ListView仅在设备上滚动时更新,但在虚拟设备上正常工作?

时间:2014-11-29 07:52:16

标签: java android multithreading listview

我最近开始学习android开发(我也是java的新手),我目前正在开发聊天/信使应用程序

正如标题所说,我面临的问题是,除非滚动,否则显示消息的列表视图不会在设备上更新,但它在虚拟机上运行正常。到目前为止,我只在LG Optimus l5 II进行了测试,但无论如何我还需要解决此问题。

我认为它与多线程有关,因为直到我添加了一些新线程才会发生这种情况,所以我认为listview,android manifest和rest的适配器设置正确。如果它有帮助我可以添加它们。

我添加的2个主题可能会导致此问题:

  1. 检查连接状态,如果断开连接则尝试重新连接。
  2. 用于与服务器通信的线程。
  3. 我测试仅在第二个线程打开时运行,问题仍然存在。

    我想指定这是我第一次尝试这样的东西(服务器 - 客户端,多线程,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());
                }   
            }   
        }
    

1 个答案:

答案 0 :(得分:0)

这里可能存在多种问题,但跳出来的有两个:

  1. 您正在从UI线程外部调用DisplayNewMessage()
  2. 您没有通知适配器其数据集已更改。
  3. 我建议您在后台查看更好的机制来执行任务,而不仅仅是创建一个Thread。使用AsyncTasks将是一个良好的开端,但您需要特别注意处理配置更改之间的任务(例如旋转设备)。

    此外,当您将方法名称大写时,您的代码很难阅读。这违反了Java代码约定。您可以通过整齐地格式化代码(一个好的IDE帮助它)并学习遵循惯例来使自己更容易!