出现问题:在详情页以及内页,少数用户获取用户id时出现空指针
分析:
1.用户保存不应该存在问题
如果用户保存出问题,则列表页就应该出现问题,而非详情页。

2.网络获取数据不应该存在问题
如果网络获取数据错,则所有用户都会出现问题,而非部分用户,并且应该是列表页出问题。

3.n那么应是获取数据的时候出了问题,因为获取用户的时候是这样写的:
public void getUser(String id){
for(int i = 0; i < users.length; i++){
if(users.get(i).getID() == id){
return user;
}
}
return null;
}
所以,这里有个猜想,应该是传入的id有问题,id是通过一个封装类从sharepreferences获取的,那么,很有可能是这个类出问题,所以我一直盯着这个类看,终于找到了问题所在,大家来找茬,你看一下能找到问题吗?

public class ShareUtils
private String shareName = "A";
private int shareMode = Context.MODE_PRIVATE;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
private static ShareUtils shareUtils;

private ShareUtils(){}
public static ShareUtils getInstance(){
if(shareUtils == null)
shareUtils = new ShareUtils();
return shareUtils;
}

private SharedPreferences getShare(){
if(sharedPreferences == null){
sharedPreferences = App.getSuperContext().getSharedPreferences(shareName,shareMode);
}
return sharedPreferences;
}

public ShareUtils resetShare(){
commit();

this.shareName = "B";
this.shareMode = Context.MODE_PRIVATE;

return this;
}

/**
* ShareUtils在同一个类中要调用不同share,进行重置
* @param shareName
* @return
public ShareUtils resetShare(String shareName){
commit();

this.shareName = shareName;
this.shareMode = Context.MODE_PRIVATE;
return this;
}

/**
* ShareUtils在同一个类中要调用不同share,进行重置
* @param shareName
* @return
public ShareUtils resetShare(String shareName, int shareMode){
commit();

this.shareName = shareName;
this.shareMode = shareMode;
return this;
}

private SharedPreferences.Editor getEditor(){
if(editor == null){
editor = getShare().edit();
}
return editor;
}

public ShareUtils set(String name,int intValue){
getEditor().putInt(name,intValue);
return this;
}

public ShareUtils set(String name,long longValue){
getEditor().putLong(name,longValue);
return this;
}

public ShareUtils set(String name,boolean boolValue){
getEditor().putBoolean(name,boolValue);
return this;
}

public ShareUtils set(String name,float floatValue){
getEditor().putFloat(name,floatValue);
return this;
}

public ShareUtils set(String name,String stringValue){
getEditor().putString(name,stringValue);
return this;
}

public ShareUtils set(String name, Set<String> stringSet){
getEditor().putStringSet(name,stringSet);
return this;
}

public void commit(){
if(editor!=null){
editor.apply();
}
}

public void clear(){
getEditor().clear().apply();
}

public void remove(String name){
getEditor().remove(name).apply();
}

public int getInt(String name){
return getShare().getInt(name,0);
}

public int getInt(String name,int defaultValue){
return getShare().getInt(name,defaultValue);
}

public long getLong(String name){
return getShare().getLong(name,0);
}

public long getLong(String name,long defaultValue){
return getShare().getLong(name,defaultValue);
}

public boolean getBoolean(String name){
return getShare().getBoolean(name,false);
}

public boolean getBoolean(String name,boolean defaultValue){
return getShare().getBoolean(name,defaultValue);
}

public float getFloat(String name){
return getShare().getFloat(name,0f);
}

public float getFloat(String name,float defaultValue){
return getShare().getFloat(name,defaultValue);
}

public String getString(String name){
return getShare().getString(name,"");
}

public String getString(String name,String defaultValue){
return getShare().getString(name,defaultValue);
}

public Set<String> getSet(String name){
return getShare().getStringSet(name,null);
}

public Set<String> getSet(String name,Set<String> defaultValue){
return

此处给你5分钟找一下。。。然后突然想到了,问题在于:
ShareUtils.getInstance().resetShare().getString(“xx”);

ShareUtils.getInstance().resetShare(“xx”).getString(“xx”);
两句一起用的时候,resetShare没有起作用!因为此时resetShare虽然更改了shareName,但是没有重置SharePreferences所以错了,当SharePreferences变量被回收以后,重新获取,就会找不到变量了,因为shareName保存的有错了,所以每个resetShare都要加上如下判断才合理:

if(!this.shareName.equals(shareName) || this.shareMode!=shareMode){
sharedPreferences = null;
}

整体如下:

public class ShareUtils
private String shareName = "A";
private int shareMode = Context.MODE_PRIVATE;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
private static ShareUtils shareUtils;

private ShareUtils(){}
public static ShareUtils getInstance(){
if(shareUtils == null)
shareUtils = new ShareUtils();
return shareUtils;
}

private SharedPreferences getShare(){
if(sharedPreferences == null){
sharedPreferences = App.getSuperContext().getSharedPreferences(shareName,shareMode);
}
return sharedPreferences;
}

public ShareUtils resetShare(){
commit();
if(!this.shareName.equals("B") || this.shareMode!=Context.MODE_PRIVATE){
sharedPreferences = null;
}
this.shareName = "B";
this.shareMode = Context.MODE_PRIVATE;

return this;
}

/**
* ShareUtils在同一个类中要调用不同share,进行重置
* @param shareName
* @return
public ShareUtils resetShare(String shareName){
commit();
if(!this.shareName.equals(shareName) || this.shareMode!=Context.MODE_PRIVATE){
sharedPreferences = null;
editor = null;
}
this.shareName = shareName;
this.shareMode = Context.MODE_PRIVATE;
return this;
}

/**
* ShareUtils在同一个类中要调用不同share,进行重置
* @param shareName
* @return
public ShareUtils resetShare(String shareName, int shareMode){
commit();
if(!this.shareName.equals(shareName) || this.shareMode!=shareMode){
sharedPreferences = null;
editor = null;
}
this.shareName = shareName;
this.shareMode = shareMode;
return this;
}

private SharedPreferences.Editor getEditor(){
if(editor == null){
editor = getShare().edit();
}
return editor;
}

public ShareUtils set(String name,int intValue){
getEditor().putInt(name,intValue);
return this;
}

public ShareUtils set(String name,long longValue){
getEditor().putLong(name,longValue);
return this;
}

public ShareUtils set(String name,boolean boolValue){
getEditor().putBoolean(name,boolValue);
return this;
}

public ShareUtils set(String name,float floatValue){
getEditor().putFloat(name,floatValue);
return this;
}

public ShareUtils set(String name,String stringValue){
getEditor().putString(name,stringValue);
return this;
}

public ShareUtils set(String name, Set<String> stringSet){
getEditor().putStringSet(name,stringSet);
return this;
}

public void commit(){
if(editor!=null){
editor.apply();
}
}

public void clear(){
getEditor().clear().apply();
}

public void remove(String name){
getEditor().remove(name).apply();
}

public int getInt(String name){
return getShare().getInt(name,0);
}

public int getInt(String name,int defaultValue){
return getShare().getInt(name,defaultValue);
}

public long getLong(String name){
return getShare().getLong(name,0);
}

public long getLong(String name,long defaultValue){
return getShare().getLong(name,defaultValue);
}

public boolean getBoolean(String name){
return getShare().getBoolean(name,false);
}

public boolean getBoolean(String name,boolean defaultValue){
return getShare().getBoolean(name,defaultValue);
}

public float getFloat(String name){
return getShare().getFloat(name,0f);
}

public float getFloat(String name,float defaultValue){
return getShare().getFloat(name,defaultValue);
}

public String getString(String name){
return getShare().getString(name,"");
}

public String getString(String name,String defaultValue){
return getShare().getString(name,defaultValue);
}

public Set<String> getSet(String name){
return getShare().getStringSet(name,null);
}

public Set<String> getSet(String name,Set<String> defaultValue){
return

解决小概率bug依据是三点:1.查看统计结果,找到出现问题的节点,以及出现问题的机型。如果机型>=6.0,那么应该是权限问题或者是回收问题,如果特定机型款,则需要特殊的机型进行测试,还原测试。2.推理,排查不可能的点,检查剩下的点。3.询问用户,bug的触发方式,机型。