-1

So, firstly I answer at your question "Are you really? There are lots of answers on it.". Yes, I know, but I really try to resolve this problem like a third day: in all SOF there are no question on my error. I have 2 similar projects: in Java and in Kotlin. But this f@#^%!@ing error only in Kotlin. But XML is identity 100%.

So, error is: android.view.InflateException: Binary XML file line #8: Error inflating class fragment.

My activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layoutMain"
    android:orientation="vertical">

    <fragment
        android:id="@+id/top_fragment"
        android:name="com.example.weatherapp_kotlin.fragments.TopFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">
    </fragment>

    <fragment
        android:id="@+id/bottom_fragment"
        android:name = "com.example.weatherapp_kotlin.fragments.BottomFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="4">
    </fragment>
</LinearLayout>

What i tried to do:

  • To change android:name ="" in XML to class = ""
  • To set android:name or class on a first position
  • To change LinearLayout to RelativeLayout and ConstraintLayout
  • To change class extends to FragmentActivity (now is Fragment and in Java it works fine)
  • To clean project

My LinearLayout has an id, an orientation. Path to classes in android:name are true.

I try to use fragments by this class:

class StartActivity: Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
}}

Maybe it's a hardcode, but in Java it works fine. I think that I don't need to show TopFragment.kt and BottomFragment.kt because I tried to tell you everything that I found in SOFs themes. But if you need - I'll show. However, an error is in XML file, so probably XML is the reason.

The complete stacktrace:

06-14 15:24:10.161 25861-25861/com.example.weatherapp_kotlin E/AndroidRuntime: FATAL EXCEPTION: main
                                                                           Process: com.example.weatherapp_kotlin, PID: 25861
                                                                           java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.weatherapp_kotlin/com.example.weatherapp_kotlin.StartActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
                                                                               at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2472)
                                                                               at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2534)
                                                                               at android.app.ActivityThread.access$800(ActivityThread.java:174)
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:111)
                                                                               at android.os.Looper.loop(Looper.java:194)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5550)
                                                                               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:955)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750)
                                                                            Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
                                                                               at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
                                                                               at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
                                                                               at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
                                                                               at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                                                                               at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
                                                                               at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:418)
                                                                               at android.app.Activity.setContentView(Activity.java:2172)
                                                                               at com.example.weatherapp_kotlin.StartActivity.onCreate(StartActivity.kt:9)
                                                                               at android.app.Activity.performCreate(Activity.java:6003)
                                                                               at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
                                                                               at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2425)
                                                                               at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2534) 
                                                                               at android.app.ActivityThread.access$800(ActivityThread.java:174) 
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424) 
                                                                               at android.os.Handler.dispatchMessage(Handler.java:111) 
                                                                               at android.os.Looper.loop(Looper.java:194) 
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5550) 
                                                                               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:955) 
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750) 
                                                                            Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
                                                                               at com.example.weatherapp_kotlin.fragments.TopFragment.onCreateView(TopFragment.kt:0)
                                                                               at android.app.Fragment.performCreateView(Fragment.java:2069)
                                                                               at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:875)
                                                                               at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1050)
                                                                               at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1152)
                                                                               at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2142)
                                                                               at android.app.Activity.onCreateView(Activity.java:5347)
                                                                               at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
                                                                               at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
                                                                               at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
                                                                               at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
                                                                               at android.view.LayoutInflater.inflate(LayoutInflater.java:365) 
                                                                               at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:418) 
                                                                               at android.app.Activity.setContentView(Activity.java:2172) 
                                                                               at com.example.weatherapp_kotlin.StartActivity.onCreate(StartActivity.kt:9) 
                                                                               at android.app.Activity.performCreate(Activity.java:6003) 
                                                                               at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129) 
                                                                               at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2425) 
                                                                               at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2534) 
                                                                               at android.app.ActivityThread.access$800(ActivityThread.java:174) 
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424) 
                                                                               at android.os.Handler.dispatchMessage(Handler.java:111) 
                                                                               at android.os.Looper.loop(Looper.java:194) 
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5550) 
                                                                               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:955) 
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750)  

TopFragment.class:

class TopFragment : Fragment(), SwipeRefreshLayout.OnRefreshListener {

private var outputCity: String = getString(R.string.output_city)
private var outputClouds: String = getString(R.string.output_clouds)
private var outputHumidity: String = getString(R.string.output_humidity)
private var outputPressure: String = getString(R.string.output_pressure)
private var outputWindspeed: String = getString(R.string.output_windspeed)
private var outputMmhg: String = getString(R.string.output_mmHg)
private var outputMs: String = getString(R.string.output_ms)

private var date: Date = Date()
private var dateFormat: SimpleDateFormat = SimpleDateFormat("E, dd.MM")

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle): View? {
    return inflater.inflate(R.layout.fragment_top, container, false)
}

override fun onStart() {
    super.onStart()

    swipeToRefresh.setOnRefreshListener(this)
    swipeToRefresh.setColorSchemeColors(Color.GREEN, Color.RED, Color.BLUE, Color.CYAN)

    checkInternetConnection(activity)
}

override fun onRefresh() {
    Handler().postDelayed({
        getData(activity)
        swipeToRefresh.setRefreshing(false)
    }, 2500)
}

fun checkInternetConnection(c: Context) {
    if (InternetConnection().isNetworkAvailable(activity)) {
        getData(activity)
    } else {
        Toast.makeText(activity, "Internet Connection Error", Toast.LENGTH_LONG).show()
    }
}

fun getData(c: Context) {
    val apiServiceWeather = RetrofitClient().getApiServiceWeather()
    val call: Call<WeatherModel> = apiServiceWeather.getMyJSON();
    call.enqueue(object: Callback<WeatherModel> {

        override fun onResponse(call: Call<WeatherModel>?, response: Response<WeatherModel>?) {
            val humidity: Int? = response!!.body().getMainWeather().humidity
            val pressure: Float? = response.body().getMainWeather().pressure
            val temperature: Float? = response.body().getMainWeather().temp
            val windspeed: Float? = response.body().getWind().windspeed
            val clouds: Int? = response.body().getClouds().clouds

            textViewDate.setText((dateFormat!!.format(date).toString()))
            textViewCity.setText(outputCity)
            textViewTemp.setText(((Math.rint(temperature!! - 273.15) * 10.0) / 10.0).toString()
                    + "°C")
            textViewCondition.setText(response.body().getWeather().get(0).description)
            textViewClouds.setText(outputClouds + " " + clouds.toString() + "%")
            textViewPressure.setText(outputPressure + " " + (Math.round(pressure!! / 1.3332239))
                    .toString() + " " + outputMmhg)
            textViewHumidity.setText(outputHumidity + " " + humidity.toString() + "%")
            textViewWindspeed.setText(outputWindspeed + " " + windspeed.toString() + outputMs)
        }

        override fun onFailure(call: Call<WeatherModel>?, t: Throwable?) {
            Toast.makeText(activity, "onResponse Error", Toast.LENGTH_LONG).show()
        }
    })
}

}

  • There's more info in the stack trace than just the Exception message on the first line. Look further on. – Mike M. Jun 14 '17 at 10:28
  • Does TopFragment class exist? Is ProGuard enabled? Are you using `android.app.Fragment` or v4 fragments? – Miha_x64 Jun 14 '17 at 10:28
  • 1
    @Miha_x64 yes, ofc, TopFragment is exist. To my shame, idk anything about ProGuard. And I use `android.app.Fragment` –  Jun 14 '17 at 10:33
  • 1
    @MikeM. I looking for it about second-third day. Really, all stack is inspected by me –  Jun 14 '17 at 10:35
  • OK, then what's the root cause? An `InflateException` is thrown whenever anything goes wrong during inflation. That by itself doesn't tell you much. – Mike M. Jun 14 '17 at 10:41
  • @MikeM. and how can I found out and solve the root cause if it doesn't tell me much? –  Jun 14 '17 at 10:49
  • What is the rest of the stack trace? – Mike M. Jun 14 '17 at 11:04
  • Post the complete stack trace. – Mike M. Jun 14 '17 at 11:11
  • @MikeM. Complete. Hope it will help you to solve it. –  Jun 14 '17 at 11:22
  • Yeah, see the `Caused by: java.lang.IllegalStateException`? That's what you want to investigate. The `InflateException` isn't the actual problem. – Mike M. Jun 14 '17 at 11:24
  • Anyway, you can't access the `Activity` in the `Fragment`'s constructor, or outside of any method, which it looks like is what you're doing, either directly or indirectly, somehow. Looks like you're trying to get a `String` resource there. – Mike M. Jun 14 '17 at 11:26
  • @MikeM. Maybe TopFragment's code will help you? –  Jun 14 '17 at 11:41
  • If you would like us to have a look for the specific problem, then yeah, you'll need to post that. – Mike M. Jun 14 '17 at 11:51
  • @MikeM. Added and I hope we'll solve it –  Jun 14 '17 at 11:58
  • Yeah, all those `getString()` calls can't be where you have them now. The earliest you can access the `Activity` and resources is when `onAttach()` happens, but you just can move those calls to `onStart()`. – Mike M. Jun 14 '17 at 12:05
  • @MikeM. It doesnt helped me. I just deleted all string resourses and the same error there. –  Jun 14 '17 at 12:26
  • If you completely removed all of those `getString()` calls, then the stack trace should have changed. – Mike M. Jun 14 '17 at 12:29
  • @MikeM. Changes added –  Jun 14 '17 at 12:34
  • Hm I just also pointed at the getString calls, which may or may not have been solved now. Anyway, new problem is that you declared onCreateView with `savedInstanceState: Bundle` but should be `savedInstanceState: Bundle?`. State is always null the first time. – RobCo Jun 14 '17 at 12:37
  • @RobCo yes, you're right. How could I miss that.. So, you are getting my vote. Thanks a lot! –  Jun 14 '17 at 12:45

1 Answers1

1

Caused by: java.lang.IllegalStateException: Fragment TopFragment{37d52abb} not attached to Activity
...
at com.example.weatherapp_kotlin.fragments.TopFragment.(TopFragment.kt:24)

I expect that would be the first line of the private vars, where you call getString() to get a String from the resources.

These fields are initialised during object construction, but at this time the fragment is not attached to any Context. getString() needs a Resources objects which comes from the Context.
This crash would happen also if you just create an instance yourself (ie. call it's constructor).

The reason its wrapped an inflate exception is because these fragments are created while parsing the xml layout. It finds the instruction to create and include the fragment, it does so but fails.

Possible solutions

1) Wrap the calls to getString in a lazy delegate. This will delay the call to when the property is first accessed, so you just have to make sure you only access these properties when you are sure the fragment is attached. For example, inside onCreateView().

private var outputCity by lazy { getString(R.string.output_city) }

2) Mark the variables with lateinit, and initialise when first attached to context. Now you have to make sure you never access the properties before that, or you are greeted with a PropertyNotInitialisedException.

private lateinit var outputCity: String

override fun onAttach(context: Activity) {
    super.onAttach(context)
    outputCity = getString(R.string.output_city)
    ...
}
RobCo
  • 6,240
  • 2
  • 19
  • 26