我这里似乎有一个奇怪的问题。我有一个带有5个文本视图的自定义适配器的ArrayList。我能够第一次添加到此列表中就可以保存并保存甚至重新加载,但是在重新加载后,我的Adapter类在尝试向列表中添加另一个项目时在getter方法上抛出了空指针。我知道NUll指针,但是问题出在试图将另一个项目添加到列表中吗?我的适配器类仅适用于1个视图吗?我不知道为什么它为null或为什么一开始它不是null。这是堆栈跟踪
更新的堆栈跟踪
08-04 14:23:17.855 10000-10000/com.apklegion.cltoollog E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.apklegion.cltoollog, PID: 10000
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.ArrayList.get(int)' on a null object reference
at com.apklegion.cltoollog.ToolListAdapter.getView(ToolListAdapter.java:34)
at android.widget.AbsListView.obtainView(AbsListView.java:2346)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1281)
at android.widget.ListView.onMeasure(ListView.java:1188)
at android.view.View.measure(View.java:18805)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:716)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:462)
at android.view.View.measure(View.java:18805)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:18805)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:400)
at android.view.View.measure(View.java:18805)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18805)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18805)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5952)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
at android.view.View.measure(View.java:18805)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
,这里是指出错误的适配器类。 更新以反映当前错误
public class ToolListAdapter extends ArrayAdapter<Toolinfo> {
private Context mcontext;
int mResource;
public ToolListAdapter(Context context, int resource, ArrayList<Toolinfo>
objects) {
super(context, resource, objects);
mcontext = context;
mResource = resource;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull
ViewGroup parent) {
-error is here> String part_number =
objects.get(position).getPart_number();
String serial_number = objects.get(position).getSerial_number();
int employee_number = objects.get(position)).getEmployee_nummber();
String date_out = objects.get(position).getOut_time();
String date_in = objects.get(position).getIn_time();
Toolinfo toolinfo = new Toolinfo(part_number,serial_number,employee_number,date_out,date_in);
LayoutInflater layoutInflater = LayoutInflater.from(mcontext);
convertView = layoutInflater.inflate(mResource,parent,false);
TextView parnum = (TextView)convertView.findViewById(R.id.patnum);
TextView sernum = (TextView)convertView.findViewById(R.id.sernum);
TextView empnum = (TextView)convertView.findViewById(R.id.empnum);
TextView timeout = (TextView)convertView.findViewById(R.id.timeout);
TextView timein = (TextView)convertView.findViewById(R.id.timein);
parnum.setText(part_number);
sernum.setText(serial_number);
empnum.setText(String.valueOf(employee_number));
timeout.setText((date_out));
timein.setText((date_in));
return convertView;
}
}
这是吸气剂和吸气剂
public class Toolinfo {
private String part_number;
private String serial_number;
private int employee_nummber;
private String out_time;
private String in_time;
public Toolinfo(String part_number, String serial_number, int employee_nummber, String out_time, String in_time){
this.part_number = part_number;
this.serial_number = serial_number;
this.employee_nummber = employee_nummber;
this.out_time = out_time;
this.in_time = in_time;
}
public String getPart_number() {
return part_number;
}
public void setPart_number(String part_number) {
this.part_number = part_number;
}
public String getSerial_number() {
return serial_number;
}
public void setSerial_number(String serial_number) {
this.serial_number = serial_number;
}
public int getEmployee_nummber() {
return employee_nummber;
}
public void setEmployee_nummber(int employee_nummber) {
this.employee_nummber = employee_nummber;
}
public String getOut_time() {
return out_time;
}
public void setOut_time(String out_time) {
this.out_time = out_time;
}
public String getIn_time() {
return in_time;
}
public void setIn_time(String in_time) {
this.in_time = in_time;
}
} 最后但并非最不重要的是存放ArrayList的主要活动类的相关位
public class MainActivity extends AppCompatActivity {
List<String> list = new ArrayList<>();
ArrayAdapter<String> adapter;
ListView listView;
Button button;
static final int ADD_TOOL = 1;
CustomAdapter customAdapter;
public static final String PREFS_NAME = "MyPreferencesFile";
final String[] tools = {"30-200 Torque Wrench","Calipers","Push Pull Gague"};
String date_out,date_in;
String part_number,serial_number;
int employee_number;
Context context;
ArrayList<Toolinfo> toolinfos;
String currentDateandTime;
DatabaseHelper db;
Toolinfo tool1;
public static String TAG =“ Main”;
ToolListAdapter myadapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolinfos = new ArrayList<>();
myadapter = new ToolListAdapter(this,R.layout.logrowlayout,toolinfos );
loadData();
button = findViewById(R.id.button);
listView = findViewById(R.id.listview);
listView.setAdapter(myadapter);
Intent getData = getIntent();
if(getData.hasExtra("part number")&& getData.hasExtra("serial number") && getData.hasExtra("employee number")) {
final String part_number = getData.getStringExtra("part number");
showToast("has extras");
String serial_number = getData.getStringExtra("serial number");
showToast(serial_number);
int employee_number = getData.getIntExtra("employee number", 0);
// showToast(String.valueOf(employee_number));
//addItems(part_number, serial_number, employee_number);
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy_HHmmss");
String currentDateandTime = sdf.format(new Date());
populateData(part_number,serial_number,employee_number,date_out,"out");
}else {
showToast("info not present");
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addTool();
}
});
}
public void populateData(String part_number,String serial_number,int employee_number, String date_out, String date_in) {
//loadData();
SimpleDateFormat sdf = new SimpleDateFormat("MMdd");
String currentDateandTime = sdf.format(new Date());
Toolinfo tool = new Toolinfo(part_number, serial_number, employee_number, currentDateandTime, "out");
myadapter.add(tool);
myadapter.notifyDataSetChanged();
saveData(tool);
for (int i = 0; i < toolinfos.size(); i++) {
Log.d(TAG, "populateData: " + toolinfos.get(i));
//toolinfos.add(tool1);
}
}
private void saveData(Toolinfo tool1) {
SharedPreferences preferences = getSharedPreferences("Shared prefs", MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
Gson gson = new Gson();
String json = gson.toJson(tool1);
editor.putString("toolobj",json);
showToast(json);
editor.commit();
//Log.i("tag",json.toString());
editor.apply();
showToast("Data Saved");
}
private void loadData(){
SharedPreferences preferences = getSharedPreferences("Shared prefs", MODE_PRIVATE);
Gson gson = new Gson();
String json = preferences.getString("toolobj","");
if (json == null){
showToast("no data");
}else {
Toolinfo tool1 = gson.fromJson(json, Toolinfo.class);
toolinfos.add(tool1);
}
}
private void addTool(){
Intent i = new Intent(MainActivity.this,Toolsignout.class);
startActivity(i);
saveData(tool1);
}
public void showToast(String msg){
Toast.makeText(this,msg,Toast.LENGTH_LONG).show();
}
@Override
protected void onResume() {
// loadData();
super.onResume();
}
}
答案 0 :(得分:0)
在您的ToolsListAdapter
中为ArrayList<Toolinfo> objects;
添加类变量,并分配与上下文相似的变量。
然后在您的getView()
方法中,将getItem(position)
更改为objects.get(position)
。
答案 1 :(得分:-1)
您只保存一个对象并在SharedPreferences中加载一个对象。
private void saveData(Toolinfo tool1) { SharedPreferences preferences = getSharedPreferences("Shared prefs", MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); Gson gson = new Gson(); String json = gson.toJson(tool1); editor.putString("toolobj",json); showToast(json); editor.commit(); editor.apply(); showToast("Data Saved"); } private void loadData(){ SharedPreferences preferences = getSharedPreferences("Shared prefs", MODE_PRIVATE); Gson gson = new Gson(); String json = preferences.getString("toolobj",""); if (json == null){ showToast("no data"); }else { Toolinfo tool1 = gson.fromJson(json, Toolinfo.class); toolinfos.add(tool1); } }
在您的load方法上,json永远不会等于null。如果首选项没有得到一个对象,它将返回一个空字符串。因此,将始终转到else块。现在,如果json不是有效的json或无法反序列化为Toolinfo对象,则gson.fromJson将不会引发任何异常。相反,它将仅返回null。因此,您要将null添加到列表中。
此外,请记住:
共享首选项是键值对。如果要保存项目列表或记录,则可能需要查看数据库。
TL; DR
您的代码结构仅保存一个值,您可以尝试将列表保存为共享首选项。将加载方法上的if语句从检查json字符串是否为null更改为empy。并且,在将对象添加到列表之前,请检查该对象是否为空。