NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
На самом деле легко вызвать операцию для замены фрагмента.
Вам нужно использовать getActivity ():
((MyActivity) getActivity())
. Тогда вы можете вызывать методы из MyActivity, например :
((MyActivity) getActivity()).replaceFragments(Object... params);
Конечно, это предполагает, что у вас есть метод replaceFragments () в вашей деятельности, который обрабатывает процесс замены фрагмента.
Редактировать: @ismailarilik добавил возможный код replaceFragments в этом коде с первым комментарием ниже, который был написан @ silva96:
Код replaceFragments может быть:
public void replaceFragments(Class fragmentClass) {
Fragment fragment = null;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment)
.commit();
}
из официальных документов:
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
В этом примере newFragment заменяет любой фрагмент (если он есть) в настоящее время в контейнере макета, идентифицированном идентификатором R.id.fragment_container
. Вызывая addToBackStack()
, замененный фрагмент сохраняется в фоновом стеке, поэтому пользователь может отменить транзакцию и вернуть предыдущий фрагмент, нажав кнопку «Назад».
Поведение, которое вы описали, является именно тем, что фрагменты предназначены для этого. Прочтите официальное руководство для полного понимания фрагментов, которые будут устранять все ваши вопросы.
http://developer.android.com/guide/components/fragments.html
Так же, как сказал Марсин, у вас не должно быть фрагмента, начинающегося с другого фрагмента или активности. Лучший способ справиться с этой ситуацией - создать реализацию обратного вызова для основного действия для обработки запросов, таких как запуск нового фрагмента. Здесь - отличный пример в руководстве разработчика Android.
Обратите внимание, что фрагмент НЕ должен непосредственно заменять себя или любые другие фрагменты. Фрагменты должны быть отдельными объектами. Какой фрагмент должен сделать, так это сообщить родительской активности о том, что произошло какое-то событие. Но это опять-таки не фрагментная работа, чтобы решить, что с этим делать! Это должно быть действием, чтобы принять решение о замене фрагмента на телефоне, но, то есть добавлении другого в существующий на планшетах. Таким образом, вы в основном делаете что-то неправильно по дизайну.
И, как уже упоминалось, ваша деятельность должна использовать FragmentManager («родной» или из библиотеки совместимости) для выполнения задания (например, replace()
или add()
или remove()
):
http://developer.android.com/guide/components/fragments.html
public void replaceFragments(Class fragmentClass) {
Fragment fragment = null;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
}
– silva96 3 August 2015 в 14:51