我正在开发一个将在没有互联网连接的情况下使用的应用程序。用户必须在转到该字段之前导入将由城市使用的数据。该应用程序第一次带来了来自城市的所有数据。这是问题,我应该如何处理?一些城市的数据太多,有时超过4000个生产者,每个生产者都有超过40个领域。
这是我的处理程序类:
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
private 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 );
//Liberar memoria.
httpEntity = null;
}catch( UnsupportedEncodingException e )
{
e.printStackTrace();
}catch( ClientProtocolException e )
{
e.printStackTrace();
}catch( IOException e )
{
e.printStackTrace();
}
return response;
}
}
当我从webservice获取所有字符串时,我在响应行处获得了OOM。 这是我调用服务器的代码:
// Instancia para adicionar os parâmetros.
List<NameValuePair> params = new ArrayList<NameValuePair>();
// 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);
我使用AsyncTask来进行调用。我使用MAT并且JSONString占用了我的应用程序所具有的大部分内存。我应该如何处理这个问题?一次只导入一些数据?
答案 0 :(得分:2)
您需要采取几种方法来解决这个问题。
首先,正如评论中所建议的那样,尝试让您的服务器返回更少的数据。这似乎是一个明显的解决方案,但它需要在连接的两端进行工作。
其次,解析来自stream的数据:
您目前正在做的是将响应转换为String
,然后传回String
,然后将其解析为JSON。这里更好的方法是从http实体处理JSON解析,如下所示(仅显示相关代码)。
public Object makeServiceCall( String url, int method, List<NameValuePair> params ) {
....
httpEntity = httpResponse.getEntity();
httpResponse = null;
JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE);
response = parser.parse( httpEntity.getContent() );
显然,你需要捕获解析异常等等,但这就是它的要点。我用HttpUrlConnection做了这个,并且能够为静态负载处理几个兆字节的响应。
据我所知,主要问题不是整体内存使用量,而是容纳响应所需的最大内存块大小。在直接解析InputStream
时,这不是问题,因为它创建了许多不需要连续堆的较小对象。