【问题标题】:Android - filled ListActivity Database Search - HowTo?Android - 填充 ListActivity 数据库搜索 - HowTo?
【发布时间】:2011-03-30 12:56:38
【问题描述】:

我得到了一个 ListActivity,它填充了数据库中的数据。该活动也允许在数据库中搜索数据。

DatabaseHelper dbHelper;
SimpleCursorAdapter adapter;
Cursor c;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    final Intent queryIntent = getIntent();
    final String queryAction = queryIntent.getAction();
    if (Intent.ACTION_SEARCH.equals(queryAction)) {
        String searchKeywords = queryIntent.getStringExtra(SearchManager.QUERY);
        doSearch(searchKeywords);
    }
}

@Override
public void onStart() {
    try {
        super.onStart();
        dbHelper=new DatabaseHelper(this);
        c = dbHelper.getAllMagazines();
        startManagingCursor(c);

        adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_2, c,
                new String[] {"editionName", "magazineName"},
                new int[] {android.R.id.text1, android.R.id.text2});

        /** Adapter setzen**/
        this.setListAdapter(adapter);
    }
    catch(Exception ex) {
    }
}

它在 ListView 中向我显示数据库中的数据。所以这里没有问题。 当我进行搜索时,会调用以下函数:

private void doSearch(String search) {    
    dbHelper=new DatabaseHelper(this);
    c = dbHelper.searchEditions(getIntent().getStringExtra("search"));
    startManagingCursor(c);

    adapter = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_2, c,
            new String[] {"editionName", "magazineName"},
            new int[] {android.R.id.text1, android.R.id.text2});

    this.setListAdapter(adapter);
}

我将 ListAdapter 设置为带有 Searchresults 的新适配器。但在搜索的 ResultView 中,它仍然显示我在 onStart() 中获取的数据库中的所有数据。如果我在 onStart() 中禁用 setListAdapter,一切正常,它会显示搜索结果。

当 ListView 已经填满数据时,如何让 ListView 显示搜索结果?

完整代码:

public class MagazineViewController extends ListActivity { 

    DatabaseHelper dbHelper;
    SimpleCursorAdapter adapter;
    Cursor c;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        final Intent queryIntent = getIntent();
        final String queryAction = queryIntent.getAction();
        if (Intent.ACTION_SEARCH.equals(queryAction)) {
            String searchKeywords = queryIntent.getStringExtra(SearchManager.QUERY);
            doSearch(searchKeywords);
        }
    }

    @Override
    public void onStart() {
        try {
            super.onStart();
            dbHelper=new DatabaseHelper(this);

            c = dbHelper.getAllMagazines();
            startManagingCursor(c);

            Log.d("CURSOR COUNT", ""+c.getCount());

            adapter = new SimpleCursorAdapter(this,
                    android.R.layout.simple_list_item_2, c,
                    new String[] {"editionName", "magazineName"},
                    new int[] {android.R.id.text1, android.R.id.text2});

            this.setListAdapter(adapter);
        }
        catch(Exception ex) {
        }
    }

    private void doSearch(String search) {    
        dbHelper=new DatabaseHelper(this);

        /** Daten aus der Datenbank abfragen**/
        Cursor cur = dbHelper.searchEditions(getIntent().getStringExtra("search"));
        startManagingCursor(cur);

        Log.d("CURSOR COUNT", ""+cur.getCount());

        final ListView view = getListView();
        final SimpleCursorAdapter cursorAdapter = ((SimpleCursorAdapter) view.getAdapter());
        cursorAdapter.changeCursor(cur);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.magazinemenu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.preferences:
                startActivity (new Intent (this, PreferencesViewController.class));
                break;
        }
        return true;
    }
}

LogCat:

 03-30 16:29:43.381: ERROR/AndroidRuntime(546): FATAL EXCEPTION: main
03-30 16:29:43.381: ERROR/AndroidRuntime(546): java.lang.RuntimeException: Unable to start activity ComponentInfo{package/package.MagazineViewController}: java.lang.NullPointerException
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.os.Looper.loop(Looper.java:123)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at java.lang.reflect.Method.invokeNative(Native Method)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at java.lang.reflect.Method.invoke(Method.java:521)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at dalvik.system.NativeStart.main(Native Method)
03-30 16:29:43.381: ERROR/AndroidRuntime(546): Caused by: java.lang.NullPointerException
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at package.MagazineViewController.doSearch(MagazineViewController.java:111)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at package.MagazineViewController.onCreate(MagazineViewController.java:40)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-30 16:29:43.381: ERROR/AndroidRuntime(546):     ... 11 more

第111行的错误码,即cursorAdapter.changeCursor(cur);

【问题讨论】:

    标签: android database search listactivity


    【解决方案1】:

    MagazineViewController.class:

    public class MagazineViewController extends ListActivity { 
    
    DatabaseHelper dbHelper;
    SimpleCursorAdapter adapter = null;
    Cursor c;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    
        final Intent queryIntent = getIntent();
        final String queryAction = queryIntent.getAction();
        if (Intent.ACTION_SEARCH.equals(queryAction)) {
            String searchKeywords = queryIntent.getStringExtra(SearchManager.QUERY);
            doSearch(searchKeywords);
        }
    
        dbHelper=new DatabaseHelper(this);
    }
    
    @Override
    public void onStart() {
        super.onStart();
    
        dbHelper=new DatabaseHelper(this);
    
        c = dbHelper.getAllMagazines();
        startManagingCursor(c);
    
        Log.d("CURSOR COUNT", ""+c.getCount());
    
        adapter = new SimpleCursorAdapter(this,
                    android.R.layout.simple_list_item_2, c,
                    new String[] {"editionName", "magazineName"},
                    new int[] {android.R.id.text1, android.R.id.text2});
    
    
        this.setListAdapter(adapter);
    }
    
    private void doSearch(String search) {    
        dbHelper=new DatabaseHelper(this);
    
        Cursor cur = dbHelper.searchEditions(search);
        startManagingCursor(cur);
    
        Log.d("CURSOR2 COUNT", ""+cur.getCount());
    
        adapter.changeCursor(cur);
    }
    

    DatabaseHelper.class:

    public class DatabaseHelper extends SQLiteOpenHelper {
    
    public static final String DATABASE_NAME = "magazineDB";
    public static final String TABLE_MAGAZINE = "magazine";
    public static final String TABLE_EDITION = "edition";
    public static final String TABLE_ARTICLE = "article";
    public static final String TABLE_KEYWORDS = "keywords";
    
    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null,1);
    }
    
    
    @Override
    public void onCreate(SQLiteDatabase db) {
    
        db.execSQL("CREATE TABLE " + TABLE_MAGAZINE + " (magazineId INTEGER PRIMARY KEY, " +
    "magazineName TEXT);");
    
        /** Tabelle "Edition" erstellen **/
        db.execSQL("CREATE TABLE " + TABLE_EDITION + " (_id INTEGER PRIMARY KEY AUTOINCREMENT," +
    "editionId INTEGER, " +
    "editionName TEXT, " +
    "editionContent TEXT, " +
    "magazine_id INTEGER NOT NULL, " +
    "FOREIGN KEY (magazine_id) REFERENCES " + TABLE_MAGAZINE + "(magazineId));");
    
        db.execSQL("CREATE TRIGGER fki_edition_magazine_id " +
                " BEFORE INSERT ON "+ TABLE_EDITION +
                " FOR EACH ROW BEGIN"+
                " SELECT CASE WHEN ((SELECT magazineId FROM "+ TABLE_MAGAZINE +" WHERE magazineId = new.magazine_id ) IS NULL)"+
                " THEN RAISE (ABORT,'Foreign Key Violation') END;"+
                "  END;");
    
    }
    
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS "+TABLE_MAGAZINE);
        db.execSQL("DROP TABLE IF EXISTS "+TABLE_EDITION);
        db.execSQL("DROP TABLE IF EXISTS "+TABLE_ARTICLE);
    
        db.execSQL("DROP TRIGGER IF EXISTS fki_edition_magazine_id");
    
        onCreate(db);
    }
    
    Cursor getAllMagazines() {
        SQLiteDatabase db=this.getWritableDatabase();
        Cursor cur= db.rawQuery("SELECT * FROM edition, magazine WHERE edition.magazine_id = magazine.magazineId", null);
        return cur; 
    }
    
    public Cursor searchEditions (String searchtext) {
        SQLiteDatabase db=this.getWritableDatabase();
        Cursor cur= db.rawQuery("SELECT * FROM edition, magazine WHERE edition.magazine_id = magazine.magazineId AND edition.editionContent LIKE '%" + searchtext + "%'" ,null);
    
        return cur;
    }
    

    【讨论】:

    • 终于找到解决办法了!我必须在 onCreate() 方法中的 doSearch() 之前初始化 ListAdapter。谢谢你的帮助!我真的很感激。
    【解决方案2】:

    尝试在现有适配器上调用 SimpleCursorAdapter.changeCursor,而不是创建新的适配器实例。

    我认为你不需要这些行:

    final ListView view = getListView();
    final SimpleCursorAdapter cursorAdapter = ((SimpleCursorAdapter) view.getAdapter());
    

    查奇:

    cursorAdapter.changeCursor(cur);
    

    收件人:

    adapter.changeCursor(cur);
    

    【讨论】:

    • 如果我更改为 adapter.changeCursor(c);我没有创建一个新的适配器实例,而是得到一个 NullPointerException。但光标数 > 0。
    • 异常是否告诉你适配器为空?你能提供你的新代码和完整的堆栈跟踪吗?您能向我们展示您的 Activity 中的所有代码吗?
    • 我之前已经尝试过了。但也会得到 NullPointerException。我不知道为什么:-/
    • 我得到的另一个错误是:Cursor cur = dbHelper.searchEditions(getIntent().getStringExtra("search"));它应该是 Cursor cur = dbHelper.searchEditions(search);仍然得到 NullPointerException 但光标计数 > 0
    • 您发布的异常是 RuntimeException,而不是 NullPointerException,那么 NullPointerException 的堆栈跟踪是什么?
    猜你喜欢
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多