尝试从数据库获取数据时耗尽内存(android)

问题描述:

我试图从我的数据库中获取一些信息。我是Android的初学者。 我有一个名为“Database”的数据库创建类和一个名为“Database_Acesso”的数据库访问类。他们看起来像这样:尝试从数据库获取数据时耗尽内存(android)

Database.java: package workshopee.ct.ufrn.br.ssmonitor;

import android.content.Context; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.util.Log; 

public class Database extends SQLiteOpenHelper{ 
    private static final int versao_db = 1; 

    private static final String nome_db = "ssmonitor_db"; 

    private static final String table1 = "phone"; 

    private static final String id = "_id"; 
    private static final String longitude = "longitude"; 
    private static final String latitude = "latitude"; 
    private static final String forca_torres = "qtdtorres"; 
    private static final String forca_dbm = "dbm"; 
    private static final String mcc = "mcc"; 
    private static final String mnc = "mnc"; 
    private static final String phone_type = "phone_type"; 
    private static final String operadora = "operadora"; 
    private static final String network_type = "networkType"; 
    private static final String cid = "cid"; 
    private static final String lac = "lac"; 

    public Database(Context context) { 
     super(context, nome_db, null, versao_db); 
    } 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     String criarTabela = "CREATE TABLE " + table1 + "(" 
       + id + " INTEGER PRIMARY KEY AUTOINCREMENT," + longitude + " REAL," 
       + latitude + " REAL," + forca_torres + " INTEGER," + forca_dbm + " REAL," + mcc + " INTEGER," 
       + mnc + " INTEGER," + phone_type + " TEXT," + operadora + " TEXT," + network_type + " INTEGER," + cid + " INTEGER," 
       + lac + " INTEGER)"; 
     db.execSQL(criarTabela); 

       } 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int versao_ant, int versao_nv) { 
     Log.w(Database.class.getName(), 
       "Atualizando o banco de dados da versão " + versao_ant + " para " 
         + versao_nv + ", isso apagará os dados antigos."); 
     db.execSQL("DROP TABLE IF EXISTS " + table1 + ";"); 
     onCreate(db); 

    } 

    public void clear (SQLiteDatabase db) { 
     Log.w(Database.class.getName(), 
       "Apagando informações salvas anteriormente."); 
     db.execSQL("DROP TABLE IF EXISTS " + table1 + ";"); 
     onCreate(db); 
    } 

} 

Database_Acesso.java:

package workshopee.ct.ufrn.br.ssmonitor; 

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 

import java.util.ArrayList; 
import java.util.List; 

public class Database_Acesso { 
    private SQLiteDatabase db; 

public Database_Acesso(Context context) { 
    Database aux_db = new Database(context); 
    db = aux_db.getWritableDatabase(); 
} 
public void inserir_phone (Phone ph) { 

    ContentValues valores = new ContentValues(); 
    valores.put("longitude",ph.getLongitude()); 
    valores.put("latitude", ph.getLatitude()); 
    valores.put("qtdtorres", ph.getTorres()); 
    valores.put("dbm", ph.getDbm()); 
    valores.put("mcc", ph.getMcc()); 
    valores.put("mnc", ph.getMnc()); 
    valores.put("phone_type", ph.getPhoneType()); 
    valores.put("operadora", ph.getOperadora()); 
    valores.put("cid",ph.getCid()); 
    valores.put("lac",ph.getLac()); 

    db.insert("phone", null, valores); 
} 


public List<Phone> buscar_phone() { 
    List<Phone> lista = new ArrayList<Phone>(); 

    String[] colunas = new String[]{"_id", "longitude", "latitude", "qtdtorres", "dbm", 
         "mcc", "mnc", "phone_type", "operadora", "networkType", "cid", "lac"}; 

    Cursor cursor = db.query("phone", colunas, null, null, null, null,"_id ASC"); 
    if (cursor.getCount() > 0) { 
     cursor.moveToFirst(); 
    } 

    do { 
     Phone p = new Phone(); 
     p.setId(cursor.getLong(0)); 
     p.setLongitude(cursor.getDouble(1)); 
     p.setLatitude(cursor.getDouble(2)); 
     p.setTorres(cursor.getInt(3)); 
     p.setDbm(cursor.getInt(4)); 
     p.setMcc(cursor.getInt(5)); 
     p.setMnc(cursor.getInt(6)); 
     p.setPhoneType(cursor.getString(7)); 
     p.setOperadora(cursor.getString(8)); 
     p.setNetWorkType(cursor.getString(9)); 
     p.setCid(cursor.getInt(10)); 
     p.setLac(cursor.getInt(11)); 
     lista.add(p); 

    } while (!cursor.isLast()); 

    return lista; 
    } 

} 

下面是我插入的MainActivity部分数据:

database_acesso.inserir_phone(cell); 

哪里database_acesso是Database_acesso的实例,电池是手机的一个实例。

这里是我如何获取信息: TextView list_text_view =(TextView)rootView.findViewById(R.id.list_text_view); List list = main.database_acesso.buscar_phone(); list_text_view.append(“ - ”+ list.size());

我在使用片段,所以“main”是MainActivity上的一个实例。 当我尝试执行它,我收到以下错误:

java.lang.OutOfMemoryError: [memory exhausted] 
     at dalvik.system.NativeStart.main(Native Method) 

它是完整的堆栈跟踪。

解决这个问题的任何想法?

Thx。

+1

你是怎么运行的?在模拟器上?也许没有足够的内存分配给模拟器? – javajavajava

您永远不会在do { ... } while()循环中调用cursor.moveToNext(),因此您不断创建新的Phone对象,直到内存用完。

一个写循环将代替是可以说是更好的办法:

Cursor cursor = db.query("phone", colunas, null, null, null, null,"_id ASC"); 

while (cursor.moveToNext()) 
{ 
    // Do stuff 
} 

...因为moveToNext()返回一个布尔值指示是否已经走到了尽头。它还将呼叫的开销节省到getCount()

+0

谢谢!它正在工作! –