Приложение вылетает, когда getContext() используется для генерации тостов внутри фрагмента в API 23, но работает в API 27 и более

#java #android

#java #Android

Вопрос:

Когда я пытаюсь сгенерировать тост в методе onCreateView из ContestFragment, используя контекст из getContext(), приложение вылетает в Android Marshmallow, хотя оно работает на Android Oreo и выше. Однако замена getContext() на getContext().getApplicationContext() устраняет проблему для Marshmallow. Может кто-нибудь, пожалуйста, описать, почему это происходит?

Примечание: getContext() не возвращает значение null. Я это проверил.

 public class ContestFragment extends Fragment {
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          View view = inflater.inflate(R.layout.fragment_contest, container, false);
          Toast.makeText(getContext(), "No Internet", Toast.LENGTH_LONG).show(); //crashes at this line

         //Toast.makeText(getContext().getApplicationContext(), "No Internet", Toast.LENGTH_LONG).show(); 
         //works

          return view;
      }
}
  

Журнал ошибок:

 09-28 20:42:36.325 31550-31550/com.hitesh.codeforces E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.hitesh.codeforces, PID: 31550
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hitesh.codeforces/com.hitesh.codeforces.MainActivity}: android.view.InflateException: Binary XML file line #27: Binary XML file line #27: Error inflating class TextView
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3319)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
        at android.app.ActivityThread.access$1100(ActivityThread.java:229)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:7331)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
     Caused by: android.view.InflateException: Binary XML file line #27: Binary XML file line #27: Error inflating class TextView
        at android.view.LayoutInflater.inflate(LayoutInflater.java:551)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:429)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:380)
        at android.widget.Toast.makeText(Toast.java:432)
        at com.hitesh.codeforces.ContestFragment.onCreateView(ContestFragment.java:66)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1266)
        at android.app.Activity.performStart(Activity.java:6943)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3276)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415) 
        at android.app.ActivityThread.access$1100(ActivityThread.java:229) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:7331) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
     Caused by: android.view.InflateException: Binary XML file line #27: Error inflating class TextView
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:794)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:716)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:847)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:810)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:527)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:429) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:380) 
        at android.widget.Toast.makeText(Toast.java:432) 
        at com.hitesh.codeforces.ContestFragment.onCreateView(ContestFragment.java:66) 
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600) 
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881) 
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238) 
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303) 
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439) 
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079) 
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869) 
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824) 
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727) 
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663) 
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613) 
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246) 
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542) 
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210) 
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1266) 
        at android.app.Activity.performStart(Activity.java:6943) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3276) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415) 
        at android.app.ActivityThread.access$1100(ActivityThread.java:229) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:7331) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
     Caused by: java.lang.ArrayIndexOutOfBoundsException: length=16; index=528
        at android.content.res.StringBlock.get(StringBlock.java:66)
        at android.content.res.XmlBlock$Parser.getPooledString(XmlBlock.java:459)
        at android.content.res.TypedArray.loadStringValueAt(TypedArray.java:1167)
        at android.content.res.TypedArray.getString(TypedArray.java:197)
        at androidx.appcompat.widget.TintTypedArray.getString(TintTypedArray.java:150)
        at androidx.appcompat.widget.AppCompatTextHelper.updateTypefaceAndStyle(AppCompatTextHelper.java:397)
        at androidx.appcompat.widget.AppCompatTextHelper.loadFromAttributes(AppCompatTextHelper.java:209)
        at androidx.appcompat.widget.A
  

XML (fragment_contest.xml ) :

 <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".ContestFragment">

    <androidx.appcompat.widget.SwitchCompat
        android:id="@ id/include"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        app:layout_constraintTop_toTopOf="parent"
        android:gravity="right"
        android:text="Show Finished"
        android:textStyle="italic"
        android:textColor="@color/white"
        android:textSize="18sp"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@ id/recycler"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp"
        app:layout_constraintTop_toBottomOf="@id/include" />

</androidx.constraintlayout.widget.ConstraintLayout>
  

Комментарии:

1. попробуйте getActivity() ?

2. попробуйте requireContext() или, возможно, view.context, но я рекомендую вам показывать тосты в методе onViewCreated, потому что вы получили раздутое представление в onCreateView, и это хорошее место для показа сообщения после раздувания представления

3. Пожалуйста, опубликуйте свой журнал сбоев, чтобы мы могли его проанализировать

4. Добавлен журнал @BogdanAndroid..

5. @JakeB getAvtivity() выдает ту же ошибку

Ответ №1:

ваша проблема в файле стиля шрифта

 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimary</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="title">Code Forces</item>
    <item name="android:letterSpacing">0.08</item>
    <item name="android:fontFamily">sans-serif</item>
</style>
  

вы не можете использовать <item name="android:fontFamily">sans-serif</item>

вы можете использовать

1- изменить на <item name="android:fontFamily">@string/font</item>

2- в строковом файле добавить строку <string name="font" translatable="false">sans-serif-light</string>

Результат:

     <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimary</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="title">Code Forces</item>
    <item name="android:letterSpacing">0.08</item>
    <item name="android:fontFamily">@string/font</item>
</style>
  

Комментарии:

1. Спасибо. Это сработало. Но если это была ошибка, то почему она работала с getApplicationContext() ?

2. И есть ли какая-либо конкретная причина, по которой «<имя элемента =»android: FontFamily»> без засечек </item>» не работает в Marshmallow, но работает в других версиях Android более высокого уровня?