Reputation: 151
I'm very new to Android, Java, and Kotlin and am trying to port my app over, originally written for iOS in Swift.
The data the app is using is an ArrayList of my Speaker object, coming from a JSON file.
My MainActivity displays a RecyclerView populated by the "brand" parameter of each speaker. The onClick for each row launches BrandMenuActivity with a recyclerView with all the speakers for that brand. The onClick for these then shows a detailView.
Everything works fine when navigating using the "hardware" back button in the emulator, but if I try to implement setDisplayHomeAsUpEnabled in the action bar of the detailView, the app crashes because the intent for BrandMenuActivity is now null.
My AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.speakerskotlin">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".SpeakerDetailActivity"
android:parentActivityName=".BrandMenuActivity">
</activity>
<activity android:name=".BrandMenuActivity"
android:parentActivityName=".MainActivity" >
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
MainActivity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.speakerToolbar))
supportActionBar?.title = "Speakers"
val jsonFileString = getJsonDataFromAsset(applicationContext, "SpeakerData.json")
val gson = Gson()
val listSpeakerType = object : TypeToken<ArrayList<Speaker>>() {}.type
val allSpeakers: ArrayList<Speaker> = gson.fromJson(jsonFileString, listSpeakerType)
brandsRecView.layoutManager = LinearLayoutManager(this)
brandsRecView.adapter = SpeakerBrandAdapter(allSpeakers){
val intent = Intent(this, BrandMenuActivity::class.java)
intent.putExtra("allSpeakers", allSpeakers)
intent.putExtra("brand", it)
startActivity(intent)
}
}
BrandMenuActivity:
class BrandMenuActivity() : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_brand_menu)
setSupportActionBar(findViewById(R.id.brandToolbar))
supportActionBar?.title = intent.getStringExtra("brand")
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val brand = intent.getStringExtra("brand")
val allSpeakers: ArrayList<Speaker> = intent.getParcelableArrayListExtra("allSpeakers")
brandMenuRecView.layoutManager = LinearLayoutManager(this.applicationContext)
brandMenuRecView.adapter = BrandMenuAdapter(brand, allSpeakers) {
val intent = Intent(this, SpeakerDetailActivity::class.java)
intent.putExtra("speaker", it)
startActivity(intent)
}
}
DetailActivity:
class SpeakerDetailActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_speaker_detail)
setSupportActionBar(findViewById(R.id.detailToolbar))
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val speaker = intent.getParcelableExtra<Speaker>("speaker")
val modelImage = findViewById<ImageView>(R.id.imgSpeakerImage)
val brandText = findViewById<TextView>(R.id.txtBrandName)
val modelText = findViewById<TextView>(R.id.txtModel)
brandText.text = speaker.brand
modelText.text = speaker.model
val resID = resources.getIdentifier(speaker.imgString, "drawable", packageName)
modelImage.setImageResource(resID)
speakerDetailRecView.layoutManager = LinearLayoutManager(this.applicationContext)
speakerDetailRecView.adapter = SpeakerDetailAdapter(speaker)
}
The Log at the time of crash:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.speakerskotlin, PID: 12099
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.speakerskotlin/com.example.speakerskotlin.BrandMenuActivity}: java.lang.IllegalStateException: intent.getParcelableArrayListExtra("allSpeakers") must not be null
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: java.lang.IllegalStateException: intent.getParcelableArrayListExtra("allSpeakers") must not be null
at com.example.speakerskotlin.BrandMenuActivity.onCreate(BrandMenuActivity.kt:20)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
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)
Upvotes: 0
Views: 176
Reputation: 15515
Two ways to do it.
First one is, you can try calling finish() while tap on android.R.id.home
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
finish()
return true
}
return super.onOptionsItemSelected(item)
}
this just resume your BrandMenuActivity
, so that onCreate will not get called, you can see complete video tutorial here.
Second one is, if you want same intent data while coming from SpeakerDetailActivity
simply pass the data between activities like as explained here
Upvotes: 1