使用AsyncTask进行内存泄漏

时间:2017-01-02 13:39:19

标签: android memory-leaks android-asynctask

我似乎有以下asyncTask的内存泄漏,可能的原因是什么?

/**
 * Async task class to get json by making HTTP call
 * */
public class PostLocation extends AsyncTask<String, Void, String>
{

    @Override
    protected void onPreExecute()
    {

    }
    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            String response = "";



            URL url = new URL(BASE_URL + "receiveLocation.php");

            myConnection = (HttpURLConnection) url.openConnection();
            myConnection.setRequestMethod("POST");
            myConnection.setDoOutput(true);

            DataOutputStream wr = new DataOutputStream(myConnection.getOutputStream());

            wr.writeBytes(params[0]);
            int responseCode = myConnection.getResponseCode();

            if (responseCode == HttpsURLConnection.HTTP_OK)
            {
                String line;
                BufferedReader br = new BufferedReader(new InputStreamReader(myConnection.getInputStream()));
                while ((line = br.readLine()) != null)
                {
                    response += line;
                }
            }
            else
            {
                return response = "";
            }
            return response;


        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "false";
        }
    }
    @Override
    protected void onPostExecute(String result)
    {
        if(result.equals("success"))
        {
            myConnection.disconnect();
        }


    }

}

这只是将一些数据发布到我的服务器上。什么可能导致内存泄漏,请注意此任务在后台使用goAsync

从广播接收器调用

2 个答案:

答案 0 :(得分:3)

这里的问题出在你的班级结构中。

应尽可能将嵌套类声明为 static ,否则会将封闭类保留在内存中,从而导致内存泄漏。

变化:

public class PostLocation extends AsyncTask<String, Void, String>

为:

public static class PostLocation extends AsyncTask<String, Void, String>

这是一个练习:

  • 在BroadcastReceiver类中放置一个名为boolean test的字段
  • 现在,在您的嵌套类中,尝试访问此字段,例如test == true

如果嵌套类不是静态,您将能够访问该字段。这是因为类的实例保留了对封闭类的引用。但是,如果您使PostLocation静态,则该字段将不可用。

答案 1 :(得分:1)

是的,您需要先关闭输入流,然后关闭httpconnection。根据{{​​3}}。

  

每个HttpURLConnection实例用于发出单个请求   与HTTP服务器的底层网络连接可能是   由其他实例透明共享。调用close()方法   在一个HttpURLConnection的InputStream或OutputStream之后   请求可以释放与此实例关联的网络资源但是   对任何共享持久连接没有影响。打电话给   disconnect()方法可能会在持久化时关闭底层套接字   此时连接处于空闲状态。

javadoc