好吧,我几乎放弃成为一名程序员并成为一名设计师。开玩笑!所以,我正在开发一个将在现场使用的应用程序,没有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服务获得响应时,会发生错误。但我不认为这是因为字符串很大。 我真的需要帮助解决这个问题,如果你能告诉我一些关于内存泄漏的提示,那就太好了。帮助来自巴西的贫困受训者,以便自己开发应用程序。