Intereting Posts
Макет экрана перемещается вверх, когда отображается клавиатура Конфигурация сервера градиента студии Android Перехватывать HTTP-запросы, отправленные из приложения Android. Обнаружите движение человека и определите его части тела, движущиеся в направлении камеры на Android Ошибка градиента, когда Theme объявляет-стиль в двух библиотеках Не могу найти подходящий пример для класса спрайтов android 2d opengl, который не использует GL11Ext для рисования КоординаторLayout игнорирует поля для просмотров с привязкой Как написать последовательную характеристику быстро и стабильно для BLE в Android? Можете ли вы определить фильтр намерений Android, используя строковый ресурс? Зачем использовать CardView вместо RelativeLayout или LinearLayout? Facebook Android Generate Key Hash AlertDialog.Builder с настраиваемым макетом и EditText; Не может получить доступ к представлению SetColorFilter () сломан на Android 4, работает на Android 5 Eclipse не запускает приложение для Android на эмуляторе во второй раз Есть ли слушатель для прослушивания изменений в томе в android?

GetActivity () возвращает значение null в функции Фрагмент

У меня есть фрагмент (F1) с общедоступным методом, подобным этому

public void asd() { if (getActivity() == null) { Log.d("yes","it is null"); } } 

И да, когда я его вызываю (из Activity), он равен null …

 FragmentTransaction transaction1 = getSupportFragmentManager().beginTransaction(); F1 f1 = new F1(); transaction1.replace(R.id.upperPart, f1); transaction1.commit(); f1.asd(); 

Это должно быть то, что я делаю очень неправильно, но я не знаю, что это такое

Solutions Collecting From Web of "GetActivity () возвращает значение null в функции Фрагмент"

commit фиксирует транзакцию, т. Е. Это происходит не сразу, а запланировано как работа над основным потоком в следующий раз, когда основной поток будет готов.

Я бы предложил добавить

 onAttach(Activity activity) 

Метод в ваш Fragment и помещая точку останова на него и видя, когда он называется относительно вашего вызова asd() . Вы увидите, что он вызывается после метода, в котором вы вызываете вызов asd() . onAttach – это то, где Fragment привязан к его активности, и с этого момента getActivity() вернет ненулевое значение (nb также есть onDetach() ).

Лучше всего избавиться от этого – сохранить ссылку на активность при вызове onAttach и использовать ссылку на активность, где это необходимо, например

 @Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = activity; } 

Это произошло, когда вы вызываете getActivity() в другом потоке, который завершен после удаления фрагмента. Типичным случаем является вызов getActivity() (например, для Toast ), когда HTTP-запрос завершен (например, в onResponse ).

Чтобы этого избежать, вы можете определить имя поля mActivity и использовать его вместо getActivity() . Это поле может быть инициализировано в методе onAttach () для фрагмента следующим образом:

 @Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = activity; } 

В моих проектах я обычно определяю базовый класс для всех своих фрагментов с помощью этой функции:

 public abstract class BaseFragment extends Fragment { protected FragmentActivity mActivity; @Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = (FragmentActivity) activity; } } 

Счастливое кодирование,

PJL прав. Я использовал его предложение, и это то, что я сделал:

  1. Определенные глобальные переменные для фрагмента:

    private final Object attachingActivityLock = new Object();

    private boolean syncVariable = false;

  2. реализованы

 @Override public void onAttach(Activity activity) { super.onAttach(activity); synchronized (attachingActivityLock) { syncVariable = true; attachingActivityLock.notifyAll(); } } 

3. Я завернул свою функцию, где мне нужно вызвать getActivity () в потоке, потому что если она будет работать в основном потоке, я бы заблокировал поток с шагом 4. и onAttach () никогда не будет вызван.

  Thread processImage = new Thread(new Runnable() { @Override public void run() { processImage(); } }); processImage.start(); 

4. В моей функции, где мне нужно вызвать getActivity (), я использую это (перед вызовом getActivity ())

  synchronized (attachingActivityLock) { while(!syncVariable){ try { attachingActivityLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } в  synchronized (attachingActivityLock) { while(!syncVariable){ try { attachingActivityLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

Если у вас есть некоторые обновления пользовательского интерфейса, не забудьте запустить их в потоке пользовательского интерфейса. Мне нужно обновить ImgeView, чтобы я сделал:

 image.post(new Runnable() { @Override public void run() { image.setImageBitmap(imageToShow); } }); 

Начиная с уровня API Android 23, onAttach (Activity activity) устарел. Вам нужно использовать onAttach (контекст контекста). http://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity)

Активность – это контекст, поэтому, если вы можете просто проверить, что контекст – это Activity, и при необходимости его приложите.

 @Override public void onAttach(Context context) { super.onAttach(context); Activity a; if (context instanceof Activity){ a=(Activity) context; } } 

Порядок, в котором вызовы вызываются после commit ():

  1. Какой бы метод вы не вызывали вручную сразу после commit ()
  2. onAttach ()
  3. onCreateView ()
  4. onActivityCreated ()

Мне нужно было сделать некоторую работу, которая включала некоторые виды, поэтому onAttach () не работал для меня; оно сломалось. Поэтому я переместил часть своего кода, который устанавливал некоторые параметры внутри метода, называемого сразу после commit () (1.), а затем в другой части кода, который обрабатывал представление внутри onCreateView () (3.).

Сделайте следующее. Я думаю, это будет полезно для вас.

 private boolean isVisibleToUser = false; private boolean isExecutedOnce = false; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_my, container, false); if (isVisibleToUser && !isExecutedOnce) { executeWithActivity(getActivity()); } return root; } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); this.isVisibleToUser = isVisibleToUser; if (isVisibleToUser && getActivity()!=null) { isExecutedOnce =true; executeWithActivity(getActivity()); } } private void executeWithActivity(Activity activity){ //Do what you have to do when page is loaded with activity } 

Где вы называете эту функцию? Если вы вызовете его в конструкторе Fragment , он вернет null .

Просто вызовите getActivity() когда выполняется метод onCreateView() .

Те, у кого еще есть проблема с onAttach (Activity activity), просто изменились на Context –

  @Override public void onAttach(Context context) { super.onAttach(context); this.context = context; } 

В большинстве случаев сохранение контекста будет достаточно для вас – например, если вы хотите сделать getResources (), вы можете сделать это прямо из контекста. Если вам все же нужно сделать контекст в своей деятельности, сделайте это –

  @Override public void onAttach(Context context) { super.onAttach(context); mActivity a; //Your activity class - will probably be a global var. if (context instanceof mActivity){ a=(mActivity) context; } } 

Как было предложено пользователем1868713.

Другие ответы, которые предполагают сохранение ссылки на активность в onAttach, просто предлагают бандад для реальной проблемы. Когда getActivity возвращает null, это означает, что Фрагмент не привязан к Activity. Чаще всего это происходит, когда активность исчезла из-за поворота или завершения действия, но в Фрагменте есть какой-то прослушиватель обратного вызова. Когда прослушиватель вызывается, если вам нужно что-то сделать с помощью Activity, но Activity ушла туда, вы не можете много сделать. В коде вы должны просто проверить getActivity() != null и если его там нет, ничего не делайте. Если вы сохраняете ссылку на пропущенную активность, вы мешаете Управлению собирать мусор. Любые пользовательские интерфейсы, которые вы можете попытаться сделать, не будут видны пользователю. Я могу представить некоторые ситуации, когда в прослушивателе обратного вызова вы можете иметь Контекст, но для чего-то не связанного с UI, в таких случаях, вероятно, имеет смысл получить контекст приложения. Обратите внимание, что единственная причина, по onAttach трюк onAttach не является большой утечкой памяти, состоит в том, что, как правило, после выполнения прослушивателя обратного вызова это больше не понадобится и может быть собрано мусором вместе с фрагментом, всем его контекстом View и Activity. Если вы setRetainInstance(true) существует большая вероятность утечки памяти, потому что поле Activity также будет сохранено, но после вращения, которое может быть предыдущим Управлением, а не текущим.

Лучший и надежный способ:

 FragmentActivity activity = (FragmentActivity) getActivity(); activity.finish();