Android中的内存不足问题

时间:2014-07-18 14:25:32

标签: android memory-leaks

好吧,我几乎放弃成为一名程序员并成为一名设计师。开玩笑!所以,我正在开发一个将在现场使用的应用程序,没有Internet。因此,用户可以访问该信息,首先他必须在进入该字段之前导入所有信息。用户可以参加许多城市,他必须导入每个城市的数据。其中一些城市有超过4000名农民注册。我试图了解更多关于内存泄漏的信息。在我不需要使用它之后,我几乎将每个对象设置为null,但这并没有解决我的问题。要导入数据,我在PHP和Android之间使用带有JSON的webservice。当我尝试逐个城市导入时,我在导入一些后得到一个OutOfMemoryError。这是LOG:

07-18 10:54:12.875: E/dalvikvm-heap(8420): Out of memory on a 16777232-byte allocation.
07-18 10:54:12.880: I/dalvikvm(8420): "AsyncTask #4" prio=5 tid=15 RUNNABLE
07-18 10:54:12.880: I/dalvikvm(8420):   | group="main" sCount=0 dsCount=0 obj=0x42ad9168 self=0x597454d0
07-18 10:54:12.880: I/dalvikvm(8420):   | sysTid=8516 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1500748904
07-18 10:54:12.880: I/dalvikvm(8420):   | state=R schedstat=( 79546994965 27092848787 165998 ) utm=6340 stm=1614 core=3
07-18 10:54:12.890: I/dalvikvm(8420):   at org.apache.http.util.CharArrayBuffer.expand(CharArrayBuffer.java:~59)
07-18 10:54:12.890: I/dalvikvm(8420):   at org.apache.http.util.CharArrayBuffer.append(CharArrayBuffer.java:77)
07-18 10:54:12.895: I/dalvikvm(8420):   at org.apache.http.util.EntityUtils.toString(EntityUtils.java:136)
07-18 10:54:12.895: I/dalvikvm(8420):   at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
07-18 10:54:12.900: I/dalvikvm(8420):   at emater.gin.webservice.ServiceHandler.makeServiceCall(ServiceHandler.java:108)
07-18 10:54:12.905: I/dalvikvm(8420):   at emater.gin.activities.ModulosActivity$DadosMunicipioWebservice.doInBackground(ModulosActivity.java:2499)
07-18 10:54:12.905: I/dalvikvm(8420):   at emater.gin.activities.ModulosActivity$DadosMunicipioWebservice.doInBackground(ModulosActivity.java:1)
07-18 10:54:12.905: I/dalvikvm(8420):   at android.os.AsyncTask$2.call(AsyncTask.java:287)
07-18 10:54:12.910: I/dalvikvm(8420):   at java.util.concurrent.FutureTask.run(FutureTask.java:234)
07-18 10:54:12.910: I/dalvikvm(8420):   at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
07-18 10:54:12.910: I/dalvikvm(8420):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
07-18 10:54:12.910: I/dalvikvm(8420):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
07-18 10:54:12.910: I/dalvikvm(8420):   at java.lang.Thread.run(Thread.java:841)
07-18 10:54:13.120: W/dalvikvm(8420): threadid=15: thread exiting with uncaught exception (group=0x41e08700)
07-18 10:54:13.125: E/AndroidRuntime(8420): FATAL EXCEPTION: AsyncTask #4
07-18 10:54:13.125: E/AndroidRuntime(8420): java.lang.RuntimeException: An error occured while executing doInBackground()
07-18 10:54:13.125: E/AndroidRuntime(8420):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at java.lang.Thread.run(Thread.java:841)
07-18 10:54:13.125: E/AndroidRuntime(8420): Caused by: java.lang.OutOfMemoryError
07-18 10:54:13.125: E/AndroidRuntime(8420):     at org.apache.http.util.CharArrayBuffer.expand(CharArrayBuffer.java:59)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at org.apache.http.util.CharArrayBuffer.append(CharArrayBuffer.java:77)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:136)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at emater.gin.webservice.ServiceHandler.makeServiceCall(ServiceHandler.java:108)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at emater.gin.activities.ModulosActivity$DadosMunicipioWebservice.doInBackground(ModulosActivity.java:2499)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at emater.gin.activities.ModulosActivity$DadosMunicipioWebservice.doInBackground(ModulosActivity.java:1)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
07-18 10:54:13.125: E/AndroidRuntime(8420):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
07-18 10:54:13.125: E/AndroidRuntime(8420):     ... 4 more
07-18 10:54:22.915: E/WindowManager(8420): Activity emater.gin.activities.ModulosActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{451a8a50 V.E..... R....... 0,0-684,290} that was originally added here
07-18 10:54:22.915: E/WindowManager(8420): android.view.WindowLeaked: Activity emater.gin.activities.ModulosActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{451a8a50 V.E..... R....... 0,0-684,290} that was originally added here
07-18 10:54:22.915: E/WindowManager(8420):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:452)
07-18 10:54:22.915: E/WindowManager(8420):  at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:258)
07-18 10:54:22.915: E/WindowManager(8420):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:73)
07-18 10:54:22.915: E/WindowManager(8420):  at android.app.Dialog.show(Dialog.java:287)
07-18 10:54:22.915: E/WindowManager(8420):  at emater.gin.activities.ModulosActivity$DadosMunicipioWebservice.onPreExecute(ModulosActivity.java:2456)
07-18 10:54:22.915: E/WindowManager(8420):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
07-18 10:54:22.915: E/WindowManager(8420):  at android.os.AsyncTask.execute(AsyncTask.java:534)
07-18 10:54:22.915: E/WindowManager(8420):  at emater.gin.activities.ModulosActivity$5.onClick(ModulosActivity.java:328)
07-18 10:54:22.915: E/WindowManager(8420):  at android.view.View.performClick(View.java:4475)
07-18 10:54:22.915: E/WindowManager(8420):  at android.view.View$PerformClick.run(View.java:18786)
07-18 10:54:22.915: E/WindowManager(8420):  at android.os.Handler.handleCallback(Handler.java:730)
07-18 10:54:22.915: E/WindowManager(8420):  at android.os.Handler.dispatchMessage(Handler.java:92)
07-18 10:54:22.915: E/WindowManager(8420):  at android.os.Looper.loop(Looper.java:176)
07-18 10:54:22.915: E/WindowManager(8420):  at android.app.ActivityThread.main(ActivityThread.java:5419)
07-18 10:54:22.915: E/WindowManager(8420):  at java.lang.reflect.Method.invokeNative(Native Method)
07-18 10:54:22.915: E/WindowManager(8420):  at java.lang.reflect.Method.invoke(Method.java:525)
07-18 10:54:22.915: E/WindowManager(8420):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
07-18 10:54:22.915: E/WindowManager(8420):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
07-18 10:54:22.915: E/WindowManager(8420):  at dalvik.system.NativeStart.main(Native Method)
07-18 10:54:29.695: I/Process(8420): Sending signal. PID: 8420 SIG: 9

WindowLeak正在发生,因为活动已关闭,而ProgressDialog已打开。剩下的错误我不知道为什么。在发生此错误之前,dalvikvm在日志中给我:

07-18 10:54:12.810: I/dalvikvm-heap(8420): Forcing collection of SoftReferences for 16777232-byte allocation
07-18 10:54:12.875: D/dalvikvm(8420): GC_BEFORE_OOM freed 10K, 64% free 21345K/57992K, paused 65ms, total 65ms

我试图改进我的代码以避免消耗太多内存,即发生错误的代码。

这是我的处理程序类,我用来调用webservice:

PS:忘了评论,这是葡萄牙语,我来自巴西。

package emater.gin.webservice;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

/*
 * Classe: ServiceHandler
 * Usada para leitura e envio de JSON.
 */
public class ServiceHandler 
{

    //Resposta
    static String response = null;

    //Recebe do servidor.
    public final static int GET = 1;

    //Envia para o servidor.
    public final static int POST = 2;

    //Construtor vazio.
    public ServiceHandler() {}

    //Faz a chamada para o servidor.
    public String makeServiceCall( String url, int method )
    {

        return this.makeServiceCall( url, method, null );

    }

    //Faz a chamada para o servidor.
    public String makeServiceCall( String url, int method, List<NameValuePair> params )
    {

        try
        {

            //HTTP Client.
            DefaultHttpClient httpClient = new DefaultHttpClient();

            //Entidade que pode ser enviada ou recebida.
            HttpEntity httpEntity = null;

            //Resposta HTTP.
            HttpResponse httpResponse = null;

            //Checa o tipo de request que vai ser feito.
            if( method == POST )
            {

                //Cria o HttpPost para enviar uma entidade.
                HttpPost httpPost = new HttpPost( url );

                //Adicona os parametros ao post.
                if( params != null )
                {

                    //Seta a entidade de respostas no httppost com os parametros passados.
                    httpPost.setEntity( new UrlEncodedFormEntity( params ) );

                }

                //Pega a resposta do servidor a partida da enviada.
                httpResponse = httpClient.execute( httpPost );

            }else if( method == GET )
            {

                //Adiciona os parametros e gera a URL.
                if( params != null )
                {

                    String paramString = URLEncodedUtils.format( params, "utf-8" );

                    url += "?" + paramString;

                }

                HttpGet httpGet = new HttpGet( url );

                //Envia a URL e pega a resposta.
                httpResponse = httpClient.execute( httpGet );

            }

            //Liberar memoria.
            httpClient = null;

            //Pega a resposta e bota em uma nova entidade para ser usada.
            httpEntity = httpResponse.getEntity();

            //Liberar memoria.
            httpResponse = null;

            response = EntityUtils.toString( httpEntity );

        }catch( UnsupportedEncodingException e ) 
        {

            e.printStackTrace();

        }catch( ClientProtocolException e ) 
        {

            e.printStackTrace();

        }catch( IOException e )
        {

            e.printStackTrace();

        }

        return response;

    }

}

以下是我如何调用服务器:

// Instancia para adicionar os parâmetros.
List<NameValuePair> params = new ArrayList<NameValuePair>();

// Mostra o progesso aos poucos.
publishProgress(1);

// Adiciona os parametros a serem passados para o webservice.
params.add(new BasicNameValuePair(
            MunicipioUsuarioController.COLUMN_MUNICIPIO_ID, municipioId));

params.add(new BasicNameValuePair("numeroserie", Secure.getString(
            getApplicationContext().getContentResolver(),
            Secure.ANDROID_ID)));

// Instancia quem vai lidar com o webservice.
ServiceHandler serviceHandler = new ServiceHandler();

// Faz um request a URL e pega a resposta.
String JSONString = serviceHandler.makeServiceCall(
HTTP_URL_DADOS_MUNICIPIO, ServiceHandler.POST, params);

当我从Web服务获得响应时,会发生错误。但我不认为这是因为字符串很大。 我真的需要帮助解决这个问题,如果你能告诉我一些关于内存泄漏的提示,那就太好了。帮助来自巴西的贫困受训者,以便自己开发应用程序。

0 个答案:

没有答案