具有 AutoCompleteTextView 的 SimpleCursorAdaptor 在 HTC 设备上的 onItemClick 处给出 NullPointerException

发布于 2024-12-16 19:10:07 字数 3842 浏览 3 评论 0原文

我有一个问题,我尝试了几种不同的失败解决方案。

我有一个 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 文本返回 null。但我不确定为什么。

以下是 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;
    }
});

I have a problem that I have tried several different failed solutions for.

I have a AutoCompleteTextView with a SimpleCursorAdaptor tied to my database to pull the names of products. When a user searches for a product, the name shows up fine. It is when they click on the product that a NullPointerException comes up and crashes the app. And the funny thing is, it only happens on HTC Devices. My Samsung works, my buddies Motorola works, the Emulator works. Just not a HTC.

Here is the stack trace from a User submitted from the 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)

Line 571 is:

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

I believe that it the TextView text is returning null. But I am unsure why.

Below is part of class 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;
    }
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鲜血染红嫁衣 2024-12-23 19:10:07

在出现错误的代码中添加日志,并查看它是否从 HTC 设备的 Logcat 返回值。处理该设备的文本视图可能存在差异。执行一些系统检查它们是否为空。

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

如果它只为 HTC 设备返回 null,那么您需要找到解决方法,因为您的视图层次结构逻辑错误(这里看起来没问题)或者 HTC 设备存在错误。如果是这种情况很难解决,那么祝你好运。

Add a log at your code where you are getting the error and see if it's returning a value from the HTC device's Logcat. It's probably that there's a difference in handling the text view for that device.Do some system out to check if they are null or not.

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

If it is returning a null for the HTC device only then you need to find a workaround for it's either your view hierarchy logic is wrong ( which seems okay here) or there's a bug for HTC devices.If that's the case pretty tough to solve then have good luck.

少女七分熟 2024-12-23 19:10:07

我找到了一个很好的解决方案来解决我的问题!我已经摆脱了 SimpleCursorAdaptor 并实现了我自己的方法。我还确定一些设备对 UI 的处理方式不同。所以我实现了一种强力方法来从 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();
                }
        }
    });

I have found a great solution to my problem! I have gotten rid of the SimpleCursorAdaptor and implemented my own method. I have also determined that several devices handles the UI differently. So i implemented a brute force method to get the data from 4 different methods. If one fails, it moves on to the next one. But one method should always get the data. Here is the code:

    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();
                }
        }
    });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文