SimpleCursorAdaptor с AutoCompleteTextView, дающим исключение NullPointerException в onItemНажмите на устройствах HTC - PullRequest
1 голос
/ 16 ноября 2011

У меня есть проблема, для которой я пробовал несколько разных неудачных решений.

У меня есть AutoCompleteTextView с SimpleCursorAdaptor, привязанным к моей базе данных, чтобы получить названия продуктов. Когда пользователь ищет продукт, имя отображается хорошо. Когда они нажимают на продукт, возникает исключение NullPointerException и происходит сбой приложения. И самое забавное, это происходит только на устройствах HTC. У меня самсунг работает, у меня приятели моторола работает, эмулятор работает. Просто не HTC.

Вот трассировка стека от пользователя, отправленного из Android Market.

java.lang.NullPointerException
at enders.pos.test.PointOfSale$8.onItemClick(PointOfSale.java:571)
at android.widget.AutoCompleteTextView.onCommitCompletion(AutoCompleteTextView.java:921)
at com.android.internal.widget.EditableInputConnection.commitCompletion(EditableInputConnection.java:78)
at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:309)
at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:75)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3835)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
at dalvik.system.NativeStart.main(Native Method)

Строка 571:

Cursor c = shop.getProdByName(text.getText().toString());

Я считаю, что текст TextView возвращает ноль. Но я не уверен, почему.

Ниже приведена часть класса PointOfsale:

final int[] to = new int[] { android.R.id.text1 };
final String[] from = new String[] { "name" };

SimpleCursorAdapter Autoadapter =
        new SimpleCursorAdapter(this,
                android.R.layout.simple_dropdown_item_1line, null,
                from, to);

textView = (AutoCompleteTextView) findViewById(R.id.autoproduct);       
textView.setAdapter(Autoadapter);
textView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> listView, View view, int position, long id) {

        TextView text = (TextView) view;

        Cursor c = shop.getProdByName(text.getText().toString());

        if(c != null){
            if(c.getColumnIndex("_id") >= 0){
                Product product = new Product();

                product.setId(c.getInt(c.getColumnIndex("_id")));
                product.setBarcode(c.getString(c.getColumnIndex("barcode")));
                product.setName(c.getString(c.getColumnIndex("name")));
                product.setDesc(c.getString(c.getColumnIndex("desc")));
                product.setPrice(c.getFloat(c.getColumnIndex("price")));
                product.setCat(c.getInt(c.getColumnIndex("catid")));

                cart.AddProduct(product);
                c.close();
            }else{
                alertbox("Not Found", "Product not found");
            }
        }else{
            alertbox("Not Found", "Product not found");
        }

        textView.setText("");
        ((ProductAdapter) inventoryList.getAdapter()).notifyDataSetChanged();
    }
});

Autoadapter.setCursorToStringConverter(new CursorToStringConverter() {
    public String convertToString(android.database.Cursor cursor) {
        // Get the label for this row out of the "state" column
        final int columnIndex = cursor.getColumnIndexOrThrow("name");
        final String str = cursor.getString(columnIndex);
        return str;
    }
});

// Set the FilterQueryProvider, to run queries for choices
// that match the specified input.
Autoadapter.setFilterQueryProvider(new FilterQueryProvider() {
    public Cursor runQuery(CharSequence constraint) {
        // Search for states whose names begin with the specified letters.
        Cursor cursor = ProductDatabase.helper.fetchItemsByName(
                (constraint != null ? constraint.toString() : null));
        return cursor;
    }
});

Ответы [ 2 ]

0 голосов
/ 30 ноября 2011

Я нашел отличное решение моей проблемы!Я избавился от SimpleCursorAdaptor и реализовал свой собственный метод.Я также определил, что несколько устройств обрабатывают пользовательский интерфейс по-разному.Поэтому я реализовал метод грубой силы, чтобы получить данные 4 различными методами.Если один терпит неудачу, он переходит к следующему.Но один метод всегда должен получать данные.Вот код:

    Autoadapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_dropdown_item_1line);
    Autoadapter.setNotifyOnChange(true);

    textView = (AutoCompleteTextView) findViewById(R.id.autoproduct);       
    textView.setAdapter(Autoadapter);
    textView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> listView, View view, int position, long id) {

            boolean isAGo = false;
            String item = null;
            Cursor c = null;

            if(listView != null){
                item = listView.getItemAtPosition(position).toString();
                c = shop.getProdByName(item);
                isAGo = true;
            }

            if(isAGo == false){
                if(view != null){
                    TextView text = (TextView) view;
                    c = shop.getProdByName(text.getText().toString());
                    isAGo = true;
                }
            }

            if(isAGo == false){
                if(textView.getText() != null){
                    item = textView.getText().toString();
                    c = shop.getProdByName(item);
                    isAGo = true;
                }
            }

            if(isAGo == false){
                if(prodList.length > 0){
                    item = prodList[0];
                    c = shop.getProdByName(item);
                    isAGo = true;
                }
            }   

            if(c != null){
                if(c.getColumnIndex("_id") >= 0){
                    Product product = new Product();

                    product.setId(c.getInt(c.getColumnIndex("_id")));
                    product.setBarcode(c.getString(c.getColumnIndex("barcode")));
                    product.setName(c.getString(c.getColumnIndex("name")));
                    product.setDesc(c.getString(c.getColumnIndex("desc")));
                    product.setPrice(c.getFloat(c.getColumnIndex("price")));
                    product.setCat(c.getInt(c.getColumnIndex("catid")));

                    cart.AddProduct(product);
                }else{
                    alertbox("Not Found", "Product not found");
                }
            }else{
                alertbox("Error", "Unable to retrieve product.");
            }

            textView.setText("");
            ((ProductAdapter) inventoryList.getAdapter()).notifyDataSetChanged();
        }
    });

    textView.addTextChangedListener(new TextWatcher() {

        public void afterTextChanged(Editable s) {}
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {

                prodList = ProductDatabase.helper.fetchItemsByName(s.toString());
                if(prodList != null){
                    Autoadapter.clear();
                    for (int i = 0; i < prodList.length; i++)
                    {
                        Log.v("Items", "Item: " + prodList[i]);
                        Autoadapter.add(prodList[i]);
                    }
                }else{
                    Autoadapter.clear();
                }
        }
    });
0 голосов
/ 16 ноября 2011

Добавьте в свой код журнал, в котором вы получаете сообщение об ошибке, и посмотрите, возвращает ли он значение из Logcat устройства HTC. Вероятно, есть какая-то разница в обработке текстового представления для этого устройства. Некая система проверяет, являются ли они нулевыми или нет.

System.out.println(text,text.getText().toString());

Если он возвращает нулевое значение только для устройства HTC, то вам нужно найти обходной путь, потому что это либо неверная логика иерархии ваших представлений (что здесь нормально), либо есть ошибка для устройств HTC. Если это довольно сложный случай чтобы решить, тогда удачи.

...