android - 如何在 android 中处理大数据?

标签 android multithreading sqlite listview

我怎样才能在 android 中解决这个问题?

07-07 14:44:58.122: E/CursorWindow(12281): Could not allocate CursorWindow '/storage/emulated/0/Android/data/com.example.mytestlistview/Mafatih/Mafatih.db' of size 2097152 due to error -12.

我在 10MB 的数据库上创建了一个 SearchBox 。它显示了 ListView 上的搜索结果,但出现了这个错误。

我的 StructNote.java :

public class StructNote {
    public String Title;
    public String Comment;

    public StructNote(String Title,String Comment)
    {
        super();
        this.Title = Title;
        this.Comment = Comment;
    }

    public String getTitle()
    {
        return Title;
    }


    public String getComment()
    {
        return Comment;
    }
}

我的 MainActivity.java :

public class MainActivity extends ActionBarActivity {
    public static final String DIR_SDCARD = Environment
            .getExternalStorageDirectory().getAbsolutePath();
    public static final String DIR_DATABASE = DIR_SDCARD + "/Android/data/";
    public ArrayList<StructNote> notes = new ArrayList<StructNote>();
    public ArrayAdapter adapter;
    public String Titel_Drawer;
    public Integer titleID;
    public Cursor cursorid;
    public ArrayList<String> array;
    public static String PACKAGE_NAME;
    EditText editText;
    DB db = new DB(MainActivity.this);
    public Cursor cursor;
    public SQLiteDatabase sql;
    public ListView lstContent;
    int selectedId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PACKAGE_NAME = getApplicationContext().getPackageName();
        File file = new File(DIR_DATABASE + PACKAGE_NAME + "/Mafatih");
        file.mkdirs();
        db.GetPackageName(PACKAGE_NAME);
        db.CreateFile();
        try {
            db.CreateandOpenDataBase();
        } catch (IOException e) {
            e.printStackTrace();
        }
        sql = db.openDataBase();

        final ListView lstContent = (ListView) findViewById(R.id.lstContent);
        adapter = new AdapterNote(notes);
        lstContent.setAdapter(adapter);

        editText = (EditText) findViewById(R.id.search);

        editText.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_ENTER) {
                        if (editText.getText().length() < 2) {
                            Toast.makeText(MainActivity.this, "Please enter more text !", Toast.LENGTH_SHORT).show();
                            return true;
                        }
                        else
                        {
                            populateListView(editText.getText());
                            return true;
                        }
                    }
                    else if(keyCode == KeyEvent.KEYCODE_DEL) {
                        adapter.clear();
                        return false;
                        }
                return false;
            }
        });

        final RadioGroup radioGroup = (RadioGroup) findViewById(R.id.Language);

        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup arg0, int arg1) {
                selectedId = radioGroup.getCheckedRadioButtonId();
                Log.i("xxx", String.valueOf(selectedId));

            }
        });
    }

    public void populateListView(Editable editable) {
        if(selectedId == 2131034177)
        {
        try {
            cursor = sql.rawQuery(
                    "SELECT * FROM WebSite_MetaDataDBBack WHERE Comment LIKE '"
                            +"%"+ editable + "%'", null);
            array = new ArrayList<String>();
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    do {
                        StructNote note = new StructNote(Titel_Drawer, Titel_Drawer);
                        note.Comment = cursor.getString(cursor
                                .getColumnIndex("Comment"));
                        titleID = cursor.getInt(cursor
                                .getColumnIndex("CategoryID"));
                        cursorid = sql.rawQuery(
                                "SELECT Title FROM WebSite_CategoryBack WHERE CategoryID ="
                                        + titleID, null);
                        if (cursorid != null) {
                            do {
                                cursorid.moveToFirst();
                                note.Title = cursorid.getString(cursorid
                                        .getColumnIndex("Title"));
                            } while (cursorid.moveToNext());
                        }
                        notes.add(note);
                    } while (cursor.moveToNext());
                }
                adapter.notifyDataSetChanged();
                cursor.close();
            }

        } catch (Exception e) {
            Log.i("xxx", "You have an error");
        }

        }
        else if(selectedId == 2131034176)
        {
            try {
                cursor = sql.rawQuery(
                        "SELECT Tafsir,CategoryID FROM WebSite_MetaDataDBBack WHERE Tafsir LIKE '"
                                +"%"+ editable + "%'", null);
                array = new ArrayList<String>();
                if (cursor != null) {
                    if (cursor.moveToFirst()) {
                        do {
                            StructNote note = new StructNote(Titel_Drawer, Titel_Drawer);
                            note.Comment = cursor.getString(cursor
                                    .getColumnIndex("Tafsir"));
                            titleID = cursor.getInt(cursor
                                    .getColumnIndex("CategoryID"));
                            cursorid = sql.rawQuery(
                                    "SELECT Title FROM WebSite_CategoryBack WHERE CategoryID ="
                                            + titleID, null);
                            if (cursorid != null) {
                                do {
                                    cursorid.moveToFirst();
                                    note.Title = cursorid.getString(cursorid
                                            .getColumnIndex("Title"));
                                } while (cursorid.moveToNext());
                            }
                            notes.add(note);

                        } while (cursor.moveToNext());
                    }
                    adapter.notifyDataSetChanged();
                    cursor.close();
                }

            } catch (Exception e) {
                Log.i("xxx", "You have an error");
            }

        }
    }
}

我的 AdapterNote.java :

public class AdapterNote extends ArrayAdapter<StructNote> {

    public AdapterNote(ArrayList<StructNote> array) {
        super(G.context, R.layout.dapter_notes, array);
    }

    public static class ViewHolder {

        public TextView txtTitle;
        public TextView txtDescription;

        public ViewHolder(View view) {
            txtTitle = (TextView) view.findViewById(R.id.txtTitle);
            txtDescription = (TextView) view.findViewById(R.id.txtDescription);
        }

        public void fill(ArrayAdapter<StructNote> adapter, StructNote item,
                int position) {
            txtTitle.setText(item.Title);
            txtDescription.setText(item.Comment);
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        StructNote item = getItem(position);
        if (convertView == null) {
            convertView = G.inflater.inflate(R.layout.dapter_notes, parent,
                    false);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.fill(this, item, position);
        return convertView;
    }
}

我的 G.java :

public class G extends Application{
    public static Context context;
    public static LayoutInflater inflater;

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
        inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
}

这是我的数据库 Db.java :

public class DB extends SQLiteOpenHelper{   
    public static final String DIR_SDCARD =Environment.getExternalStorageDirectory().getAbsolutePath();
    public static final String DIR_DATABASE = DIR_SDCARD +"/Android/data/";
    private static  String DB_NAME = "Mafatih.db";
    private final Context myContext;
    public static String PACKAGE_NAME;
    public boolean flag = false;

    private void copyDataBase() throws IOException{
        //Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);

        // Path to the just created empty db
        String outFileName = DIR_DATABASE +PACKAGE_NAME+"/Mafatih/"+ DB_NAME;

        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        //transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        try{
        while ((length = myInput.read(buffer))>0){
            myOutput.write(buffer, 0, length);
            }
        }
        catch (IOException e) {
            Log.e("Copy", e.toString());
        }
        //Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

       }

    private boolean checkDataBase(){
        SQLiteDatabase checkDB = null;

        try{

            checkDB = SQLiteDatabase.openDatabase(DIR_DATABASE +PACKAGE_NAME+ "/Mafatih/" + DB_NAME, null, 0);

        }catch(SQLiteException e){
         Log.e("asdf", "checkDataBase-->"+e.toString());
        }
        if(checkDB != null){
            checkDB.close();
        }
        return checkDB != null ? true : false;
       }
    @Override
    public synchronized SQLiteDatabase getReadableDatabase() {
        return super.getReadableDatabase();
    }
    public DB(Context context) {
     super(context, DB_NAME, null, 1);
        this.myContext = context;
    }   


    public void CreateandOpenDataBase() throws IOException{
         boolean dbExist = checkDataBase();
         if(dbExist){
         }
         else
         {
        try {
                copyDataBase();
            } 
        catch (IOException e) {
            throw new Error("Error copying database --> "+e.toString());
            }
         }
    }

    public SQLiteDatabase openDataBase() throws SQLException{
        return SQLiteDatabase.openOrCreateDatabase(DIR_DATABASE +PACKAGE_NAME+ "/Mafatih/" +DB_NAME, null);
       }


    public boolean CreateFile(){
        if(flag == false)
        {
            File file= new File(DIR_DATABASE);
            file.mkdirs();
            return true;
        }
        else
        {
            return true;
        }
    }

    public void GetPackageName(String res){
        PACKAGE_NAME = res;
    }

@Override
public void onCreate(SQLiteDatabase db) {

    }

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

最佳答案

问题: 由于错误 -12,无法分配大小为 2097152 的 CursorWindow“.....”。

原因:大多数情况下,此问题是由于未关闭游标引起的。使用后必须关闭所有游标。

在您的代码中,如果 try block 中发生任何异常,游标将不会关闭,因为控制权将传递给 catch block 。因此修改您的代码如下:

try {....}
catch{
}
finally {
   cursor.close();
}

finally block 中关闭 cursor 始终是一个好习惯。

您也没有关闭 cursorid。确保你也关闭了 cursorid

更新 1:

Why and when does this exception occur?

为了处理SQLite语句,SQLite会创建一个内存区域,称为上下文区域,其中包含处理语句所需的所有信息,例如处理的行数等。 游标是指向此上下文区域的指针。 SQLite 通过游标控制上下文区域。游标保存 SQL 语句返回的行(一个或多个)。游标保存的行集称为 Activity 集。

Cursor.close()关闭游标,释放其所有资源并使其完全无效。

因此,如果您不关闭游标,则资源(最重要的是游标指向的内存)不会被释放,这会导致泄漏,进而导致分配问题。

希望对您有所帮助。

关于android - 如何在 android 中处理大数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24608468/

相关文章:

sqlite - SQLite日期分割

java - Android 显示不同数量的 TextView

java - 获取完整的联系人电话号码和国家/地区代码,即使未输入国家/地区代码

android - 这是检查系统上是否存在罗盘传感器的正确方法吗?

c++ - 多线程之间的互斥锁

java线程似乎没有被释放

java - 试图停止线程,但它又开始了

node.js - SQLITE_BUSY Node.js 的 Azure 只读问题

android - 在 android 中检索 View 名称属性?

sqlite - 使用SQLite ATTACH