【问题标题】:arrayList String search: NullPointerExceptionarrayList 字符串搜索:NullPointerException
【发布时间】:2014-06-20 03:06:32
【问题描述】:

我会尽力解释这一点。 (我还是 Java 和 Android 的新手)

问题

我正在尝试通过搜索 arrayList 将传入的数字字符串与联系人对象的数字字符串进行比较。

背景

我能够将数组列表中的联系人加载到不同的视图(ListView、textView 等)中,因此我知道方法和对象正在工作。我遇到的问题是这个新类 (RingerService)。

设计

我在一个名为 contactStorage 的类中有一个联系人数组列表。 它可以按预期工作以显示不同的视图:

//constructor with context to access project resources and instantiate from JSONfile to arrayList 
private ContactStorage(Context appContext){
    mAppContext = appContext;
    mSerializer = new ContactJSONer(mAppContext, FILENAME);
    
    try{
        mContacts = mSerializer.loadContacts();
    }catch (Exception e){
        mContacts = new ArrayList<Contact>();
        Log.e(TAG, "No contacts available, creating new list: ", e);
    }
}

//get method to only return one instance from the constructor
public static ContactStorage get(Context c){
    if (sContactStorage == null){
        sContactStorage = new ContactStorage(c.getApplicationContext());
    }
    return sContactStorage;
}

//for ringer service to find matching number
public Contact getContactNumber(String number){
    for (Contact c: mContacts){
        if(c.getNumber().replaceAll("[^0-9]", "").equals(number))
            return c;
    }
    return null;
}

当我在下面的 RingerService 类中调用上面的 get 方法时,就会出现问题。具体来说,我在 onCallStateChanged 上收到 NullPointerException:

 private Contact mContact;
private String number;
private Context mContext;

    @Override
   public void onCreate(){
       mTelephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
       mPhoneStateListener = new PhoneStateListener(){
           // state change 
           @Override
           public void onCallStateChanged(int state, String incomingNumber){
               if (state == 1 ){ 
                   try{
                        mContact = ContactStorage.get(mContext).getContactNumber(incomingNumber);
                        number = mContact.getNumber();
                        Log.d(TAG, state+" received an incoming number: " + number);
                    }catch(Exception e){
                        Log.d(TAG, " exception: " + e);
                    }
               } else {
                   Log.d(TAG, state+" number not found" + incomingNumber);
               }
           }   
       };
       super.onCreate();
   }

疑难解答:

1. 我删除了对数字的引用 (number = mContact.getNumber();) - 在这种情况下程序运行良好。我可以向模拟器发送一个测试调用,并且日志消息正确显示,测试编号为 arg。我认为这可能是数组搜索在 getContactNumber 类中的工作方式。是不是一直找不到匹配的值,导致null?

2. 我还认为,由于这是一项服务,所以在调用 ContactStorage.get(Context c) 方法时,我无法获得正确的上下文。

3. 如果我设置了我的 mContact 引用并且没有找到数字匹配,mContact = null;还是让程序运行?

【问题讨论】:

  • 因为getContactNumber 可能会返回null,然后你右转并调用mContact.getNumber(),其中mContactgetContactNumber 的返回......这是一个等待发生的NullPointerException。
  • 您是否在任何地方初始化了您的上下文 (mContext)?我觉得你的上下文是空的。调试和检查。
  • 我在 ContactStorage 中使用 getApplicationContext() 的原因是我希望在应用程序范围内的多个领域(活动、片段、服务)中使用模型数据。既然服务是一个上下文,我可以简单地设置Context mContext = RingerService(this) 直接访问它吗?

标签: java android arraylist nullpointerexception singleton


【解决方案1】:

您正在尝试将字符串与c.getNumber() == number 中的== 匹配,这将检查两个对象引用是否相等

使用c.getNumber().equals(number)

【讨论】:

  • 您尝试匹配的number 是否在列表mContacts 中?如果不是,那么您将不得不处理代码中的 mContactnull 的情况
  • @Aniruddha for (Contact c: mContacts){ if (c.getNumber() == number) return c; } return null; 每次都返回null 作为其做参考
  • @Pallavi 之前没有看到 return null。对不起
  • 我尝试使用一个我知道已经在其中一个联系人对象上的数字,但在现实世界的场景中,比如 try,catch 异常块会更好。
【解决方案2】:

感谢您的建议。事实证明,在 Eclipse 中测试模拟器设备的来电时,GUI 字段只接受没有空格或连字符的数字:(1112221122)

由于我的联系人对象的号码字段是通过 android 的 CONTACT_URI 分配的,因此格式保存为字符串 (###) ###-####。这将永远不会匹配,从而导致 nullPointerException 错误。我更新了 getContactNumber 方法,以替换任何可能匹配的长串数字的这种格式。

然后,我在 RingerService 方法上添加了任何 RuntimeException 的捕获。现在一切正常。

出于好奇,有人知道真实来电号码的格式吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 2023-04-02
    • 2020-03-21
    相关资源
    最近更新 更多