在Android应用程序中加载PHP生成的数据时可能出现的竞争情况

时间:2015-03-09 08:57:16

标签: php android

我正在撰写处理销售数据的应用。数据输出到私人网页,我的应用程序可以访问和阅读。但是,我的应用并不总能收到它应该拥有的所有数据。 (如果我在桌面浏览器中打开网页,数据总是完整的)我怀疑这可能是由于竞争条件导致应用程序在网页完全加载之前尝试读取网页上的数据。以下是从网页读取数据的代码:

     try {
            URL url = new URL(myurl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(120000 /* milliseconds, or 2 minutes */);
            conn.setConnectTimeout(120000 /* milliseconds, or 2 minutes */);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            // Starts the query
            conn.connect();
            int response = conn.getResponseCode();
            Log.d(DEBUG_TAG, "The response is: " + response);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            is = conn.getInputStream();
            // Convert the InputStream into a string
            String contentAsString = readIt(is, len);
            return contentAsString;

            // Makes sure that the InputStream is closed after the app is
            // finished using it.
        } finally {
            if (is != null) {
                is.close();
            } 
        }

正如你所看到的,我添加了一个Thread.sleep()来给页面加载时间,这有所帮助,但还没有完全解决问题。

在尝试从网页上读取数据之前,我该怎么做才能确保应用等待网页完全加载?

编辑:这是我的readit功能:

public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
        Reader reader = null;
        reader = new InputStreamReader(stream, "UTF-8");        
        char[] buffer = new char[len];
        reader.read(buffer);
        return new String(buffer);
    }

编辑2:我已经编辑了readIt循环,直到在缓冲区中找到某个字符序列。这样可行,但如果数据加载速度不够快,则应用程序会崩溃,因为Android认为存在无限循环。这是编辑过的代码:

    public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
        boolean xyz = false;
        Reader reader = null;
        char[] buffer = null;
        while (xyz == false){
            reader = new InputStreamReader(stream, "UTF-8");        
            buffer = new char[len];
            reader.read(buffer);
            String test = new String(buffer);
            System.out.println(test);
            if (test.contains("@@@")){
                xyz = true;
            }
        }
        return new String(buffer);
    }

1 个答案:

答案 0 :(得分:0)

嗯,这是我发现的有效方法。问题是即使流没有完全加载,读者也会从流中读取。它也会从流中读取1000000个字符,即使没有多少字符要读取。这导致读者阅读可用的内容,然后使用UTF-8未知符号(�)填写剩余的1000000个字符。你在这里看到的代码在流上循环,每次读取自上一个循环以来加载的内容,并丢弃�字符。它确实要求您阅读的任何内容都不包含任何非UTF-8字符,因为它将字符串拆分为它找到的第一个字符串,但如果您正在读取UTF-8,则无论如何都应该确保这一点。它还要求您在数据末尾放置一个不常见的字符序列以标记结束。

// This converts the data stream into a String that can be manipulated.
    public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
        boolean isDone = false;     // Boolean to keep track of whether the data is loaded or not.
        Reader reader = new InputStreamReader(stream, "UTF-8");     // Input stream reader
        char[] buffer = null;       // Character array to hold the data from the stream
        String readDump = null;     // String to hold data converted from the character array, which will most likely contain junk characters.
        String splitDump [] = null;     // String array that holds the valid data and junk from readDump after they've been separated.
        String dataHolder = "";     // Output string that holds the valid data
        // While the final characters have not been read (@@@)
        while (isDone == false){        
            buffer = new char[len];
            reader.read(buffer);        // Read data from the stream
            readDump = new String(buffer);      // Turn it into a string
            splitDump = readDump.split("[\\x00\\x08\\x0B\\x0C\\x0E-\\x1F]", 2);     //Split the string into valid data and junk.
            dataHolder += splitDump[0];     // Add the valid data to the output string
            System.out.println(dataHolder);     //Debug
            if (dataHolder.contains("@@@")){
                // If the output string has the final characters in it, then we are done.
                isDone = true;
            }
        }
        return dataHolder;
    }