Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid app crashes because fragments become null
    primarykey
    data
    text
    <p>I am making an app, and whenever I either wait a long time to use the app since it has been in the background or use a Task Killer (I don't actually use Task Killers, they are just handy for bringing up bugs that would otherwise be hard to replicate) then when I press a button on my app, it crashes, and I have found through logcat it is because tempmainfrag is returning as null in the following code when used in saveButtonClicked and deleteButtonClicked methods:</p> <pre><code>public class MainActivity extends FragmentActivity implements MainListFragment.OnListSelectedListener { MainListFragment tempmainfrag; InfoFragment infofrag; int mainPosition = -1; MenuItem menuItemAdd; //plus button in ActionBar/options menu boolean menucreated = false; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mainlayout); // Check whether the activity is using the layout version with // the fragment_container FrameLayout. If so, we must add the first fragment if (findViewById(R.id.fragment_container) != null) { //meaning, if using phone version // However, if we're being restored from a previous state, // then we don't need to do anything and should return or else // we could end up with overlapping fragments. if (savedInstanceState != null) { return; } // Create an instance of MainListFragment tempmainfrag = new MainListFragment(); //made a context parameter to pass the context // In case this activity was started with special instructions from an Intent, // pass the Intent's extras to the fragment as arguments tempmainfrag.setArguments(getIntent().getExtras()); // Add the fragment to the 'fragment_container' FrameLayout getSupportFragmentManager().beginTransaction() .add(R.id.fragment_container, tempmainfrag).commit(); Log.i("mydebug","TEMPMAINFRAG: " + tempmainfrag); } } @Override public void onResume() { super.onResume(); } @Override public void onStart() { Log.i("mydebug","1"); if(menuItemAdd != null) menuItemAdd.setVisible(true); //turns on menu item 'add' super.onStart(); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); menuItemAdd = menu.findItem(R.id.menu_add); menucreated = true; return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_add: //NEED TO IMPLEMENT: MAKES ICON PRESS FOR BACK GO BACK // Create fragment infofrag = new InfoFragment(menuItemAdd); Bundle args = new Bundle(); args.putBoolean(infofrag.ARG_NEW, true); infofrag.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack so the user can navigate back transaction.replace(R.id.fragment_container, infofrag); transaction.addToBackStack(null); // Commit the transaction transaction.commit(); return true; default: return super.onOptionsItemSelected(item); } } public void onItemSelected(int position, String schedulename, String[] ampm, boolean[] days, int[] times, boolean vibrate) { // The user selected a list item //////////////////////////////TWO PANE LAYOUT STUFF/////////////////////////////////// // Capture the article fragment from the activity layout // InfoFragment articleFrag = (InfoFragment) // getSupportFragmentManager().findFragmentById(R.id.article_fragment); //article_fragment exists in layout-large // // if (articleFrag != null) { // // If article frag is available, we're in two-pane layout... // // // Call a method in the ArticleFragment to update its content // articleFrag.updateArticleView(position); // // } else { // phone layout - swap frags mainPosition = position; // Create fragment and give it an argument for the selected article infofrag = new InfoFragment(menuItemAdd); Bundle args = new Bundle(); args.putInt(infofrag.ARG_POSITION, position); //new stuff to add info args.putString(infofrag.ARG_NAME, schedulename); args.putBooleanArray(infofrag.ARG_DAYS, days); args.putIntArray(infofrag.ARG_TIMES, times); args.putBoolean(infofrag.ARG_VIBRATE, vibrate); args.putStringArray(infofrag.ARG_AMPM, ampm); args.putBoolean(infofrag.ARG_NEW, false); infofrag.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack so the user can navigate back transaction.replace(R.id.fragment_container, infofrag); transaction.addToBackStack(null); // Commit the transaction transaction.commit(); } public void saveButtonClicked(View view) { //pass the click to the mainlistfragment // MainListFragment tempmainfrag2 = (MainListFragment)getSupportFragmentManager(). // findFragmentById(R.id.fragment_container); Log.i("mydebug","TEMPMAINFRAG: " + tempmainfrag); if(!infofrag.newsched) //if existing schedule, so save { Log.i("mydebug","Saving schedule..."); boolean redo = false; //is set true every time info isnt correct when trying to save schedule //create toast Toast toast; //get title EditText titletext = (EditText)this.findViewById(R.id.titletext); //get checkboxes CheckBox check1 = (CheckBox)this.findViewById(R.id.monbox); //recreate checkboxes from view in activity (doesnt extend Activity CheckBox check2 = (CheckBox)this.findViewById(R.id.tuebox); //so use getActivity()) CheckBox check3 = (CheckBox)this.findViewById(R.id.wedbox); CheckBox check4 = (CheckBox)this.findViewById(R.id.thubox); CheckBox check5 = (CheckBox)this.findViewById(R.id.fribox); CheckBox check6 = (CheckBox)this.findViewById(R.id.satbox); CheckBox check7 = (CheckBox)this.findViewById(R.id.sunbox); CheckBox vibratebox = (CheckBox)this.findViewById(R.id.vibratecheckbox); //get times TimePicker startpicker = (TimePicker)this.findViewById(R.id.starttimepicker); TimePicker stoppicker = (TimePicker)this.findViewById(R.id.stoptimepicker); //check for input errors if(titletext.getText().toString().length() == 0) //if title is empty { redo = true; toast = Toast.makeText(view.getContext(), "Enter an event name", 4); toast.show(); //some sick-ass shake animations!!! Animation shake = AnimationUtils.loadAnimation(titletext.getContext(), R.anim.shake_big); this.findViewById(R.id.titletext).startAnimation(shake); } else if((!check1.isChecked()) &amp;&amp; (!check2.isChecked()) &amp;&amp; (!check3.isChecked()) &amp;&amp; (!check4.isChecked()) &amp;&amp; (!check5.isChecked()) &amp;&amp; (!check6.isChecked()) &amp;&amp; (!check7.isChecked())) //if all checkboxes arent checked { redo = true; toast = Toast.makeText(view.getContext(), "At least one day of week must be checked", 4); toast.show(); //more sick-ass shake animations!!! Animation shake = AnimationUtils.loadAnimation(titletext.getContext(), R.anim.shake_small); this.findViewById(R.id.checkboxes).startAnimation(shake); this.findViewById(R.id.daysofweek).startAnimation(shake); this.findViewById(R.id.frequencytext).startAnimation(shake); } if(!redo) //if all info is fine { //check to see if time goes into next day if((startpicker.getCurrentHour() &gt; stoppicker.getCurrentHour())|| ((startpicker.getCurrentHour() == stoppicker.getCurrentHour()) &amp;&amp; (startpicker.getCurrentMinute() &gt;= stoppicker.getCurrentMinute()))) { toast = Toast.makeText(view.getContext(), "Note: Stop time is earlier than start time, so this schedule stops at next day", Toast.LENGTH_LONG); toast.show(); } toast = Toast.makeText(view.getContext(), "Schedule saved", Toast.LENGTH_LONG); toast.show(); //changing old schedule to new one boolean[] tempdays = {check1.isChecked(), check2.isChecked(), check3.isChecked(), check4.isChecked(), check5.isChecked(), check6.isChecked(), check7.isChecked()}; Log.i("mydebug","Time info read from counters: Start hour: " + startpicker.getCurrentHour() + "\nStop hour: " + stoppicker.getCurrentHour()); tempmainfrag.mainObjectList.changeSchedule(mainPosition, titletext.getText().toString(), tempdays, vibratebox.isChecked(), startpicker.getCurrentHour(), startpicker.getCurrentMinute(), stoppicker.getCurrentHour(), stoppicker.getCurrentMinute()); //used to hide keyboard in case its still open when displaying list InputMethodManager imm = (InputMethodManager)this.getSystemService( Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(titletext.getWindowToken(), 0); this.onBackPressed(); //replicates backpress to go back to list } } else //if new schedule needs to be created { Log.i("mydebug","Creating new schedule..."); boolean redo = false; //create toast Toast toast; //get title EditText titletext = (EditText)this.findViewById(R.id.titletext); //get checkboxes CheckBox check1 = (CheckBox)this.findViewById(R.id.monbox); //recreate checkboxes from view in activity (doesnt extend Activity CheckBox check2 = (CheckBox)this.findViewById(R.id.tuebox); //so use getActivity()) CheckBox check3 = (CheckBox)this.findViewById(R.id.wedbox); CheckBox check4 = (CheckBox)this.findViewById(R.id.thubox); CheckBox check5 = (CheckBox)this.findViewById(R.id.fribox); CheckBox check6 = (CheckBox)this.findViewById(R.id.satbox); CheckBox check7 = (CheckBox)this.findViewById(R.id.sunbox); CheckBox vibratebox = (CheckBox)this.findViewById(R.id.vibratecheckbox); //get times TimePicker startpicker = (TimePicker)this.findViewById(R.id.starttimepicker); TimePicker stoppicker = (TimePicker)this.findViewById(R.id.stoptimepicker); EditText temppp = titletext; //check for input errors if(titletext.getText().toString().length() == 0) //if title is empty { redo = true; toast = Toast.makeText(view.getContext(), "Enter an event name", 4); toast.show(); //some sick-ass shake animations!!! Animation shake = AnimationUtils.loadAnimation(titletext.getContext(), R.anim.shake_big); this.findViewById(R.id.titletext).startAnimation(shake); } else if((!check1.isChecked()) &amp;&amp; (!check2.isChecked()) &amp;&amp; (!check3.isChecked()) &amp;&amp; (!check4.isChecked()) &amp;&amp; (!check5.isChecked()) &amp;&amp; (!check6.isChecked()) &amp;&amp; (!check7.isChecked())) //if all checkboxes arent checked { redo = true; toast = Toast.makeText(view.getContext(), "At least one day of week must be checked", 4); toast.show(); //more sick-ass shake animations!!! Animation shake = AnimationUtils.loadAnimation(titletext.getContext(), R.anim.shake_small); this.findViewById(R.id.checkboxes).startAnimation(shake); this.findViewById(R.id.daysofweek).startAnimation(shake); this.findViewById(R.id.frequencytext).startAnimation(shake); } if(!redo) //if all info is fine { //check to see if time goes into next day if((startpicker.getCurrentHour() &gt; stoppicker.getCurrentHour())|| ((startpicker.getCurrentHour() == stoppicker.getCurrentHour()) &amp;&amp; (startpicker.getCurrentMinute() &gt;= stoppicker.getCurrentMinute()))) { toast = Toast.makeText(view.getContext(), "Note: Stop time is earlier than start time, so this schedule stops at next day", Toast.LENGTH_LONG); toast.show(); } toast = Toast.makeText(view.getContext(), "Schedule created", Toast.LENGTH_LONG); toast.show(); //changing old schedule to new one boolean[] tempdays = {check1.isChecked(), check2.isChecked(), check3.isChecked(), check4.isChecked(), check5.isChecked(), check6.isChecked(), check7.isChecked()}; Log.i("mydebug","Time info read from counters: Start hour: " + startpicker.getCurrentHour() + "\nStop hour: " + stoppicker.getCurrentHour()); tempmainfrag.mainObjectList.addSchedule(titletext.getText().toString(), tempdays, vibratebox.isChecked(), startpicker.getCurrentHour(), startpicker.getCurrentMinute(), stoppicker.getCurrentHour(), stoppicker.getCurrentMinute()); //used to hide keyboard in case its still open when displaying list InputMethodManager imm = (InputMethodManager)this.getSystemService( Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(titletext.getWindowToken(), 0); this.onBackPressed(); //replicates backpress to go back to list } } } public void deleteButtonClicked(View view) { //tempmainfrag = (MainListFragment)getSupportFragmentManager(). //findFragmentById(R.id.fragment_container); if(!infofrag.newsched) //if existing schedule, so ask to delete { //make a notification AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Delete?"); builder.setIcon(R.drawable.trash_icon); builder.setMessage("Are you sure you wish to delete this schedule?") .setCancelable(false) .setPositiveButton("Delete", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { tempmainfrag.mainObjectList.removeSchedule(mainPosition); Toast toast; toast = Toast.makeText(tempmainfrag.getActivity(), "Schedule deleted", 4); toast.show(); tempmainfrag.exit(); } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); AlertDialog alert = builder.create(); alert.show(); } else //if new schedule, so just cancel tempmainfrag.exit(); } public void hideKeyboard() //hides keyboard, called whenever reverting back to list { InputMethodManager imm = (InputMethodManager)getSystemService( Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0); } } </code></pre> <p>I realize it is because in onCreate, the saveinstancestate isn't null so a new fragment isn't created, so what is a better way to do this then? I tried using </p> <pre><code>MainListFrag tempmainfrag = (MainListFragment)getSupportFragmentManager(). findFragmentById(R.id.fragment_container); </code></pre> <p>But it was giving me errors as well.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload