数据通过循环泄漏



我试图通过AsyncTask下载一个网页的html,然后在日志中显示该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();
        }
    }
}

My Logs get filled with:

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

你知道代码有什么问题吗?

你的代码的问题是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();

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

result += current;

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

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

我能够获得数据与您的代码。我相信你在测试时已经添加了互联网权限。

但是你的代码阻塞UI线程,因为task.execute().get()。我稍微改了一下:

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");

相关内容

  • 没有找到相关文章

最新更新