I’ve surpassed the AApt2 trouble and was able to execute the application and navigate to add a new crime. But as I added the code from 13.8 and 13.9 I’ve run into a run-time error.
I believe it could be my code but as far as I’ve seen from the solution mines matches. The program starts but when I click the “+” sign it crashes.
My Log:
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Enabling debug mode 0
W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@6461412 time:458765353
I/Timeline: Timeline: Activity_launch_request id:com.bignerdranch.android.criminalintent time:458770701
I/ViewRootImpl: CPU Rendering VSync enable = true
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bignerdranch.android.criminalintent, PID: 20447
java.lang.NullPointerException: Attempt to invoke virtual method ‘boolean java.lang.Boolean.booleanValue()’ on a null object reference
at com.bignerdranch.android.criminalintent.CrimeFragment.onCreateView(CrimeFragment.java:139)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1419)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2199)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:651)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:167)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1236)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1084)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
at android.view.View.measure(View.java:17550)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5579)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:17550)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5579)
at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:400)
at android.view.View.measure(View.java:17550)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5579)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.view.View.measure(View.java:17550)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5579)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17550)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5579)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2635)
at android.view.View.measure(View.java:17550)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2034)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1192)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1398)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1080)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5940)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:773)
at android.view.Choreographer.doCallbacks(Choreographer.java:586)
at android.view.Choreographer.doFrame(Choreographer.java:556)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:759)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:5255)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
I/Process: Sending signal. PID: 20447 SIG: 9
Disconnected from the target VM, address: ‘localhost:8601’, transport: ‘socket’
When I ran the debugger and stepped in to my code I was led here:
public Boolean isSolved()
{
return mSolved;
}
The debugger said the byte code and source code wasn’t a match for isSolved. The App will come on but when I click the new crime button it crashes.
When I ran the break point on the line in question:
/*You are going to store the List of crimes in a singleton. A singleton is
a class that allows only one instance of itself to be created. A singleton
exists as long as the application stays in memory, so storing the
list in a singleton will keep the crime data available
throughout any lifecycle changes in your activities and fragments.
The CrimeLab singleton is not a solution for long-term storage of data,
but it does allow the app to have one owner of the crime data and
provides a way to easily pass that data between controller classes. */
public class CrimeLab
{ //8.1 Setting up the singleton
/*To create a singleton, you create
a class with a private constructor and a get() method. */
private static CrimeLab sCrimeLab; //static variable
private List<Crime> mCrimes;
//get() for the singleton
public static CrimeLab get(Context context)
{
if (sCrimeLab == null)
{
sCrimeLab = new CrimeLab(context);
}
return sCrimeLab;
}//end get () for singleton
/*In CrimeLab’s constructor, create an empty List of Crimes.
Also, add two methods:a getCrimes() method that returns the
List and a getCrime(UUID) that returns the Crime with the given ID. */
//private constructor for the singleton
private CrimeLab(Context context)
{
mCrimes = new ArrayList<>(); //empty list of crimes
}//end private constructor for the singleton
//13.8 Adding a new crime
public void addCrime(Crime c)
{
mCrimes.add(c);
}//end adding new crime
//getCrimes()
public List<Crime> getCrimes()
{
return mCrimes;
}//end getCrimes()
//getCrime(UUID)
public Crime getCrime(UUID id)
{
for (Crime crime : mCrimes)
{
if (crime.getId().equals(id))
{
return crime;
}
}
return null;
}
public class Crime
{
/In Crime.java, add fields to
represent the crime’s ID, title, date, and
status and a constructor that initializes the ID and date fields
-----------------------------------------------------------------
7.3 Adding to Crime Class/
private UUID mId; //ID
private String mTitle; //Title
private Date mDate; //Date
private Boolean mSolved; //status
// a constructor that initializes the ID and date fields
public Crime()
{
mId = UUID.randomUUID();
mDate = new Date();
}//end constructor
/*Next, you want to generate a getter for the read-only mId and
both a getter and setter for mTitle, mDate, and mSolved. */
//getter for mId
public UUID getId()
{
return mId;
}
//getter and setters
public String getTitle()
{
return mTitle;
}
public void setTitle(String title)
{
mTitle = title;
}
public Date getDate()
{
return mDate;
}
public void setDate(Date date)
{
mDate = date;
}
public Boolean isSolved()
{
return mSolved;
}
public void setSolved(Boolean solved) {
mSolved = solved;
}
I’ve researched the error why source code and byte code do not match and what to do and come up with nothing. I’ve been stalled at the recyclerview compatibility issue and the AAPT2 issue and found the solution through research but not this time. If anyone have any insight I would greatly appreciate it. I’ve started criminal intent over twice already and I won’t be starting over a third time, I’ll just invest my time programming something else.
//12.3 Working with alertDialog
/*In CrimeFragment, add a constant for the DatePickerFragment’s tag. Then,
in onCreateView(…), remove the code that disables the date button and set a View.
OnClickListener that shows a DatePickerFragment when the date button is pressed. */
public class CrimeFragment extends Fragment
{ //10.6 Writing a newInstance(UUID)method
private static final String ARG_CRIME_ID = “crime-id”;
//12.3 Showing your DialogFragment
//Constant for DatePickerFragment's tag
private static final String DIALOG_DATE = "DialogDate";
//create a constant for the request code and then make
// CrimeFragment the target fragment of the DatePickerFragment instance.
//12.8 Setting target fragment
//request code
private static final int REQUEST_DATE = 0;
/*(1st)In CrimeFragment.java, add a member variable for the Crime
instance and an implementation of Fragment.onCreate(Bundle).
-------------------------------------------------------------
7.16 Overriding the onCreate(Bundle)method*/
private Crime mCrime; //member variable for crime
private EditText mTitleField; //variable for EditText
private Button mDateButton; //button
private CheckBox mSolvedCheckBox; //var for checkBox
//10.6 Writing a newInstance(UUID)method
public static CrimeFragment newInstance(UUID crimeId)
{
Bundle args = new Bundle();
args.putSerializable(ARG_CRIME_ID, crimeId);
CrimeFragment fragment = new CrimeFragment();
fragment.setArguments(args);
return fragment;
}//End newInstance(UUID)method
//an implementation of Fragment.onCreate(Bundle)
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Retrieving the extra and fetching the crime
//CrimeFragment fetches a Crime, its view can display that Crime’s data.
UUID crimeId = (UUID)getArguments().getSerializable(ARG_CRIME_ID);
mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);
}//end of onCreate(Bundle)
/*(2nd)In CrimeFragment.java, add an implementation
of onCreateView(…) that inflates fragment_crime.xml*/
/*(3rd) You are now going to hook up the EditText, Checkbox, and Button
in your fragment. The onCreateView(…) method is the place to wire up these widgets. */
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_crime,container, false);
//(4th) Get a reference and listener for EditText
mTitleField = (EditText) v.findViewById(R.id.crime_title);
mTitleField.setText(mCrime.getTitle()); //10.5 Updating view objects
mTitleField.addTextChangedListener(new TextWatcher()
{
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
//intentionally blank
}// end of beforeTextChanged
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
mCrime.setTitle(s.toString());
}//end of onTextChanged
@Override
public void afterTextChanged(Editable s)
{
//this one too
}//end of afterTextChanged
});//end of listener for EditText
//7.13 Setting Button text
mDateButton = (Button) v.findViewById(R.id.crime_date);
updateDate();
/*remove the code that disables the date button and set a View.
OnClickListener that shows a DatePickerFragment when the date button is pressed.*/
//mDateButton.setEnabled(false); //disables the button so it wont respond to the user
mDateButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
FragmentManager manager = getFragmentManager();
/*In CrimeFragment, remove the call to the DatePickerFragment constructor and
replace it with a call to DatePickerFragment.newInstance*/
//old 1-DatePickerFragment dialog = new DatePickerFragment();
DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());
//make CrimeFragment the target fragment of the DatePickerFragment instance.
dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE);
dialog.show(manager, DIALOG_DATE);
}
});
//7.14 Listening for checkBox changes
mSolvedCheckBox = (CheckBox)v.findViewById(R.id.crime_solved);
mSolvedCheckBox.setChecked(mCrime.isSolved());
mSolvedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
mCrime.setSolved(isChecked);
}//end onCheckedChanged
});//end of listener for CheckBox
return v;
}//end of onCreateView()
//override onActivityResult(…) to retrieve the extra,
// set the date on the Crime, and refresh the text of the date button.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode != Activity.RESULT_OK)
{
return;
} //end if
if (requestCode == REQUEST_DATE)
{
Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
mCrime.setDate(date);
updateDate();
} //end if
}//end onActivityResult
//The code that sets the button’s text is identical to code you
// call in onCreateView(…). To avoid setting the text in two places,
// encapsulate this code in a private updateDate()
// method and then call it in onCreateView(…) and onActivityResult(…).
//12.12 Highlighting date button update
private void updateDate()
{
mDateButton.setText(mCrime.getDate().toString());
}//end updateDate()