数据通过循环泄漏

时间:2016-06-29 17:31:54

标签: android android-asynctask android-studio-2.0

我试图通过AsyncTask下载网页的html,然后在LOG中显示html。

这是我的代码。但是,当我运行代码时,循环永远不会停止。

public class MainActivity extends AppCompatActivity {

    public class DownloadTask extends AsyncTask<String,Void,String>{
        @Override
        protected String doInBackground(String... urls) {

            String result = "";
            HttpURLConnection connection = null;
            URL myUrl;

            try{
                myUrl = new URL(urls[0]);
                connection = (HttpURLConnection) myUrl.openConnection();
                InputStream in = connection.getInputStream();
                InputStreamReader reader = new InputStreamReader(in);

                int data  = reader.read();
                while(data != -1){
                    char current = (char) data;
                    result += current;
                    data = reader.read();
                }
                return result;
            }
            catch(Exception e){
                e.printStackTrace();
                return "Failed";
            }
        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DownloadTask task = new DownloadTask();
        try {
            String result = task.execute("http://www.posh24.com/celebrities").get();
            Log.i("asd",String.valueOf(result));
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
}

我的日志充满了:

D/dalvikvm: GC_FOR_ALLOC freed 297K, 20% free 2582K/3200K, paused 4ms, total 4ms

任何想法代码都有问题吗?

3 个答案:

答案 0 :(得分:2)

使用单个data调用初始化代码时,read()代码的问题不会发生变化,因此它永远不会是-1(因此无限循环)。

您需要在循环内调用read()

替换以下内容:

int data  = reader.read();
while(data != -1){
    // ...

有这样的事情:

int data;
while ((data = reader.read()) != -1) {
    // ...

为了加快速度,您可以使用BufferedReader

BufferedReader reader = new BufferedReader(new InputStreamReader(in));

String line = null;
StringBuilder builder = new StringBuilder();

while((line = reader.readLine()) != null) {
    builder.append(line);
}

String data = builder.toString();

答案 1 :(得分:0)

可能是因为在收到的每个角色上都创建了一个新字符串。不要这样做:

result += current;

相反,请创建一个StringBuilder并附加到它。

或者,更好的是,不要一次读取一个字符,而是创建一个BufferedReader并读入相当大的缓冲区,例如: 1024字节。

答案 2 :(得分:0)

我可以使用您的代码获取数据。我相信你在测试时已经添加了互联网权限。

但由于task.execute()。get(),您的代码会阻止UI线程。我稍微改了一下:

public class DownloadTask extends AsyncTask<String, Void, String> {

private Listener mListener;

DownloadTask(Listener listener) {
    mListener = listener;
}

@Override
protected String doInBackground(String... urls) {

    String result = "";
    HttpURLConnection connection = null;
    URL myUrl;

    try {
        myUrl = new URL(urls[0]);
        connection = (HttpURLConnection) myUrl.openConnection();
        InputStream in = connection.getInputStream();
        InputStreamReader reader = new InputStreamReader(in);

        int data = reader.read();

        while (data != -1) {
            char current = (char) data;
            result += current;
            data = reader.read();
        }

        return result;
    } catch (Exception e) {
        e.printStackTrace();
        return "Failed";
    }
}

@Override
protected void onPostExecute(String s) {
    mListener.deliverResult(s);
}

public interface Listener {
    void deliverResult(String result);
}

}

Activity中的代码如下所示:

        DownloadTask task = new DownloadTask(new DownloadTask.Listener() {
        @Override
        public void deliverResult(String result) {
            Log.i("asd",String.valueOf(result));
        }
    });
    task.execute("http://www.posh24.com/celebrities");