当创建自定义Fragment
对象的Session
显示信息时,我需要使用所选Session
的属性加载UI。
第一次创建Fragment
时,此方法正常
我在onStart
中为设置编写了代码,因为布局不会在onCreateView
之前调用onStart
。 (http://developer.android.com/guide/components/fragments.html)
问题是:每当手机旋转时,应用程序崩溃,显然是因为onStart
被调用,
我尝试使用onActivityCreated
和onResume
代替但没有奏效,这是onCreateView
如果不禁用旋转,我该怎么办?
这里有一个很好的片段生命周期图: http://developer.android.com/guide/components/fragments.html
05-12 01:03:12.968 21599-21599/com.example.kn.ib W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x418f3da0)
05-12 01:03:12.968 21599-21599/com.example.kn.ib E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.kn.ib, PID: 21599
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.kn.ib/com.example.kn.ib.IBCentralActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3924)
at android.app.ActivityThread.access$1000(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1271)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.karimnseir.instabeat.IBSessionInfoFragment.onActivityCreated(IBSessionInfoFragment.java:117)
at android.app.Fragment.performActivityCreated(Fragment.java:1708)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:908)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1044)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1853)
at android.app.Activity.performCreate(Activity.java:5429)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3924)
at android.app.ActivityThread.access$1000(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1271)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
片段onStart(第117行是"ID: "+ session._id + "\n" +
)
@Override
public void onStart() {
super.onStart();
sessionID = activityCallback.getSelectedSessionID();
db = activityCallback.getSessionDatabase();
instabeatTimeService = new InstabeatDateAndTime();
session = db.getSession(sessionID);
TextView textViewForTesting = (TextView) getView().findViewById(R.id.test);
String testText = "\n" +
"ID: "+ session._id + "\n" +
"LAP COUNT: "+ session._lapCount + "\n" +
"DATE: "+ session._date + "\n" +
"CALORIES: "+ session._calories + "\n" +
"ISOPEN: "+ session._isOpen + "\n" +
"LASTMOD: "+ session._lastMod;
textViewForTesting.setText(testText);
Button saveButton = (Button) getView().findViewById(R.id.SessionInfo_SaveButton);
saveButton.setOnClickListener(this);
isOpenTextField = (EditText) getView().findViewById(R.id.ISOPEN);
poolSizeTextField = (EditText) getView().findViewById(R.id.POOLSIZE);
commentTextField = (EditText) getView().findViewById(R.id.COMMENT);
metricTextField = (EditText) getView().findViewById(R.id.METRIC);
Date sessionDate = instabeatTimeService.getDateFromLong(session._date);
int sessionDay = instabeatTimeService.getDayFromDate(sessionDate);
int sessionMonth = instabeatTimeService.getMonthFromDate(sessionDate);
int sessionYear = instabeatTimeService.getYearFromDate(sessionDate);
int sessionHour = instabeatTimeService.getHourFromDate(sessionDate);
int sessionMinute = instabeatTimeService.getMinuteFromDate(sessionDate);
dateField = (EditText) getView().findViewById(R.id.sessionDateField);
dateFormatter = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
dateField.setInputType(InputType.TYPE_NULL);
dateField.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
datePickerDialog.show();
}
});
dateField.setText(sessionMonth + "/" + sessionDay + "/" + sessionYear);
datePickerDialog = new DatePickerDialog(getActivity(), new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Calendar newDate = Calendar.getInstance();
newDate.set(year, monthOfYear, dayOfMonth);
dateField.setText(dateFormatter.format(newDate.getTime()));
}
},sessionYear, sessionMonth, sessionDay);
timeField = (EditText) getView().findViewById(R.id.sessionTimeField);
//TODO: set user preferences for time format HH or KK
timeFormatter = new SimpleDateFormat("HH:mm", Locale.US);
timeField.setInputType(InputType.TYPE_NULL);
timeField.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timePickerDialog.show();
}
});
timeField.setText(sessionHour + ":" + sessionMinute);
timePickerDialog = new TimePickerDialog(getActivity(), new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Calendar newTime = Calendar.getInstance();
int hr = newTime.get(Calendar.HOUR_OF_DAY);
int mn = newTime.get(Calendar.MINUTE);
/*TODO: set user preferences for time format HH or KK */
dateField.setText(hr+":"+mn);
}
},sessionHour, sessionMinute, true/*TODO: set user preferences for time format HH or KK */);
isOpenTextField.setText(session._isOpen+"");
metricTextField.setText(session._metric);
commentTextField.setText(session._comment);
poolSizeTextField.setText("" + session._poolSize);
}
答案 0 :(得分:1)
活动和片段生命周期在android上并不是微不足道的。 请记住活动和片段将被销毁并在设备轮换时重新创建,因此,如果您需要一个不再调用的方法,您可以使用片段的onCreate方法并将setRetainInstanceState(true)放在同一个方法中。通过这种方式,片段将保留并且不会在设备方向更改时被破坏。 此外,您必须在xml布局中定义片段,并且必须分配id,如果您的布局是以编程方式添加的,或者没有UI,您可以使用FragmentManager和标签来添加和检索片段。
您可以查看android handling runtime changes指南