So I would like to learn more about cameraX, the relatively new addition to the Android Jetpack library. I've been looking at an existing project on GitHub to help me understand how to set things up. However the issue is that i'm new to kotlin (project is in kotlin).
In the project: Project
there exists something called "it"
Can be seen here: Example
More specifically in the following line:
provideLayout()?.let { setContentView(it) }
"it" is repeated multiple times throughout the project as well. I just want to know what this is. Is "it" a variable? Is "it" Kotlin specific code?
Additionally, what is:
provideLayout()?.let
How does this work? What does it do?
UPDATE
Specific to CommonsWare solution (error):
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.memory.pod.debug, PID: 31521
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.memory.pod.debug/com.memory.pod.camerax.ui.home.HomeActivity}: android.view.InflateException: Binary XML file line #8 in com.memory.pod.debug:layout/activity_home: Binary XML file line #8 in com.memory.pod.debug:layout/activity_home: Error inflating class androidx.fragment.app.FragmentContainerView
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: android.view.InflateException: Binary XML file line #8 in com.memory.pod.debug:layout/activity_home: Binary XML file line #8 in com.memory.pod.debug:layout/activity_home: Error inflating class androidx.fragment.app.FragmentContainerView
Caused by: android.view.InflateException: Binary XML file line #8 in com.memory.pod.debug:layout/activity_home: Error inflating class androidx.fragment.app.FragmentContainerView
Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.arindam.camerax.ui.home.permission.PermissionsFragment: make sure class name exists
at androidx.fragment.app.FragmentFactory.loadFragmentClass(FragmentFactory.java:91)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:546)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:71)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:28)
at androidx.navigation.NavController.navigate(NavController.java:935)
at androidx.navigation.NavController.onGraphCreated(NavController.java:577)
at androidx.navigation.NavController.setGraph(NavController.java:534)
at androidx.navigation.NavController.setGraph(NavController.java:499)
at androidx.navigation.NavController.setGraph(NavController.java:481)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:237)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:303)
at androidx.fragment.app.FragmentContainerView.<init>(FragmentContainerView.java:166)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:51)
E/AndroidRuntime: at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:335)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1069)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:997)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
at android.view.LayoutInflater.inflate(LayoutInflater.java:481)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161)
at com.memory.pod.camerax.ui.base.BaseActivity.onCreate(BaseActivity.kt:11)
at android.app.Activity.performCreate(Activity.java:7825)
at android.app.Activity.performCreate(Activity.java:7814)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.ClassNotFoundException: com.arindam.camerax.ui.home.permission.PermissionsFragment
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:454)
at androidx.fragment.app.FragmentFactory.loadClass(FragmentFactory.java:47)
at androidx.fragment.app.FragmentFactory.loadFragmentClass(FragmentFactory.java:88)
... 53 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.arindam.camerax.ui.home.permission.PermissionsFragment" on path: DexPathList[[zip file "/data/app/com.memory.pod.debug-koXsvzgNs8unWof_uGUUgw==/base.apk"],nativeLibraryDirectories=[/data/app/com.memory.pod.debug-koXsvzgNs8unWof_uGUUgw==/lib/arm64, /system/lib64, /system/product/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
Side not the hyperlink highlighted section is
com.memory.pod.camerax.ui.base.BaseActivity.onCreate(BaseActivity.kt:11)
Is "it" a variable?
it
is a parameter passed into the lambda expression.
Taking this piece by piece...
provideLayout()
is a function, returning an object.
?.
is a "safe call", meaning that if the object is null
, we skip the call
?.let()
is a particular usage of a safe call that says "execute this lambda expression if the object is not null
, and pass that object in as a parameter; if the object is null
, though, skip it and let's just go have lunch"
{ setContentView(it) }
is a lambda expression that is called by let()
if the object returned by provideLayout()
is not null
, and that object is referred to in the lambda expression as it
(where it
is the default name of the lambda parameter, since we did not provide another name)
If we knew that provideLayout()
would never return null
, or if setContentView()
could support null
, this could be simplified as:
setContentView(provideLayout())