发布实施 Parcelable 和检索自定义对象
Issue Implementing Parcelable and retriving custom object
我一直在尝试将 Parcelable
实现到我的自定义对象中,以便在活动之间发送和检索它。但是,应用程序在设置对象的值时崩溃,但我不明白为什么。控制台输出如下:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.musicalstructureapp, PID: 10537
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.musicalstructureapp/com.example.musicalstructureapp.MusicPlayerActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.musicalstructureapp.Songs.getArtist()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3792)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3968)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
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:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.musicalstructureapp.Songs.getArtist()' on a null object reference
at com.example.musicalstructureapp.MusicPlayerActivity.onCreate(MusicPlayerActivity.java:21)
at android.app.Activity.performCreate(Activity.java:8198)
at android.app.Activity.performCreate(Activity.java:8182)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3765)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3968)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
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:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
这个输出是什么意思?
Attempt to invoke virtual method 'java.lang.String com.example.musicalstructureapp.Songs.getArtist()' on a null object reference
我是这样实现 Parcelable 的:
package com.example.musicalstructureapp;
import android.os.Parcel;
import android.os.Parcelable;
public class Songs implements Parcelable {
/**
* Artist's name.
*/
private String mArtist;
/**
* Album name.
*/
private String mAlbum;
/**
* Track name.
*/
private String mTrack;
/**
* Track name.
*/
private int mCover;
/**
* Create a new Song object.
*
* @param artist is the artist's name.
* @param album is the name of the album.
* @param track is the name of the track.
*/
public Songs(String artist, String album, String track, int cover) {
mArtist = artist;
mAlbum = album;
mTrack = track;
mCover = cover;
}
/**
* Get the artist's name.
*/
public String getArtist() {
return mArtist;
}
/**
* Get the album name.
*/
public String getAlbum() {
return mAlbum;
}
/**
* Get the track name.
*/
public String getTrack() {
return mTrack;
}
/**
* Get the cover of the album.
*/
public int getCover() {
return mCover;
}
@Override
public int describeContents() {
return 0;
}
/**
* Write object's data to the passed-in Parcel.
*/
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(mArtist);
parcel.writeString(mAlbum);
parcel.writeString(mTrack);
parcel.writeInt(mCover);
}
/**
* This is used to regenerate the object.
*/
public static final Parcelable.Creator<Songs> CREATOR = new Parcelable.Creator<Songs>() {
public Songs createFromParcel(Parcel in) {
return new Songs(in);
}
public Songs[] newArray(int size) {
return new Songs[size];
}
};
private Songs(Parcel in) {
mArtist = in.readString();
mAlbum = in.readString();
mTrack = in.readString();
mCover = in.readInt();
}
}
我的 TracksActivity 包含对象列表并使用 onItemClickListener 打开新的 activity 并传递对象:
package com.example.musicalstructureapp;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class TracksActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tracks);
// New list of songs
ArrayList<Songs> songs = new ArrayList<>();
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_one), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_two), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_three), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_four), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_five), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_six), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_seven), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_eight), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_nine), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_ten), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_eleven), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_twelve), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_thirteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_fourteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_fifteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_sixteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_seventeen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_eighteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_nineteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_twenty), R.drawable.cover_sample));
// Create an SongAdapter, whose data source is a list of Songs. The adapter knows how to create list items for each item in the list.
SongAdapter adapter = new SongAdapter(this, songs);
// Find the ListView object in the view hierarchy of the Activity.
// There should be a ListView with the view ID called activity_tracks_list_view, which is declared in the
// activity_tracks.xml layout file.
ListView listView = findViewById(R.id.activity_tracks_list_view);
// Make the ListView use the SongAdapter we created above, so that the
// ListView will display list items for each Songs in the list.
listView.setAdapter(adapter);
// Open new Activity on click. Passes clicked object to MusicPlayerActivity.
listView.setOnItemClickListener((parent, view, position, id) -> {
Intent openPlayer = new Intent(TracksActivity.this, MusicPlayerActivity.class);
openPlayer.putExtra("song", position);
startActivity(openPlayer);
});
}
}
activity我要取回传过来的对象:
package com.example.musicalstructureapp;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
public class MusicPlayerActivity extends TracksActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
Intent passedIntent = getIntent();
Songs song = (Songs) passedIntent.getParcelableExtra("song");
TextView currentArtist = findViewById(R.id.currentArtistName_text_view);
TextView currentTrack = findViewById(R.id.currentTrackName_text_view);
TextView currentAlbum = findViewById(R.id.currentAlbumName_text_view);
ImageView currentCover = findViewById(R.id.currentAlbumCover_image_view);
currentArtist.setText(song.getArtist());
currentTrack.setText(song.getTrack());
currentAlbum.setText(song.getAlbum());
currentCover.setImageResource(song.getCover());
}
}
将openPlayer.putExtra("song", position);
更改为openPlayer.putExtra("song", songs.get(position));
现在您正在将 int(position 是 int)值发送到您的 MusicPlayerActivity
并将其投射到 Songs。因此在 currentArtist.setText(song.getArtist());
你得到 nullpointerexception
.
我一直在尝试将 Parcelable
实现到我的自定义对象中,以便在活动之间发送和检索它。但是,应用程序在设置对象的值时崩溃,但我不明白为什么。控制台输出如下:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.musicalstructureapp, PID: 10537
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.musicalstructureapp/com.example.musicalstructureapp.MusicPlayerActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.musicalstructureapp.Songs.getArtist()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3792)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3968)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
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:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.musicalstructureapp.Songs.getArtist()' on a null object reference
at com.example.musicalstructureapp.MusicPlayerActivity.onCreate(MusicPlayerActivity.java:21)
at android.app.Activity.performCreate(Activity.java:8198)
at android.app.Activity.performCreate(Activity.java:8182)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3765)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3968)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
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:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
这个输出是什么意思?
Attempt to invoke virtual method 'java.lang.String com.example.musicalstructureapp.Songs.getArtist()' on a null object reference
我是这样实现 Parcelable 的:
package com.example.musicalstructureapp;
import android.os.Parcel;
import android.os.Parcelable;
public class Songs implements Parcelable {
/**
* Artist's name.
*/
private String mArtist;
/**
* Album name.
*/
private String mAlbum;
/**
* Track name.
*/
private String mTrack;
/**
* Track name.
*/
private int mCover;
/**
* Create a new Song object.
*
* @param artist is the artist's name.
* @param album is the name of the album.
* @param track is the name of the track.
*/
public Songs(String artist, String album, String track, int cover) {
mArtist = artist;
mAlbum = album;
mTrack = track;
mCover = cover;
}
/**
* Get the artist's name.
*/
public String getArtist() {
return mArtist;
}
/**
* Get the album name.
*/
public String getAlbum() {
return mAlbum;
}
/**
* Get the track name.
*/
public String getTrack() {
return mTrack;
}
/**
* Get the cover of the album.
*/
public int getCover() {
return mCover;
}
@Override
public int describeContents() {
return 0;
}
/**
* Write object's data to the passed-in Parcel.
*/
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(mArtist);
parcel.writeString(mAlbum);
parcel.writeString(mTrack);
parcel.writeInt(mCover);
}
/**
* This is used to regenerate the object.
*/
public static final Parcelable.Creator<Songs> CREATOR = new Parcelable.Creator<Songs>() {
public Songs createFromParcel(Parcel in) {
return new Songs(in);
}
public Songs[] newArray(int size) {
return new Songs[size];
}
};
private Songs(Parcel in) {
mArtist = in.readString();
mAlbum = in.readString();
mTrack = in.readString();
mCover = in.readInt();
}
}
我的 TracksActivity 包含对象列表并使用 onItemClickListener 打开新的 activity 并传递对象:
package com.example.musicalstructureapp;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class TracksActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tracks);
// New list of songs
ArrayList<Songs> songs = new ArrayList<>();
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_one), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_two), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_three), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_four), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_five), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_six), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_seven), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_eight), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_nine), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_ten), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_eleven), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_twelve), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_thirteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_fourteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_fifteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_sixteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_seventeen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_eighteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_nineteen), R.drawable.cover_sample));
songs.add(new Songs(getString(R.string.NF), getString(R.string.the_search), getString(R.string.track_twenty), R.drawable.cover_sample));
// Create an SongAdapter, whose data source is a list of Songs. The adapter knows how to create list items for each item in the list.
SongAdapter adapter = new SongAdapter(this, songs);
// Find the ListView object in the view hierarchy of the Activity.
// There should be a ListView with the view ID called activity_tracks_list_view, which is declared in the
// activity_tracks.xml layout file.
ListView listView = findViewById(R.id.activity_tracks_list_view);
// Make the ListView use the SongAdapter we created above, so that the
// ListView will display list items for each Songs in the list.
listView.setAdapter(adapter);
// Open new Activity on click. Passes clicked object to MusicPlayerActivity.
listView.setOnItemClickListener((parent, view, position, id) -> {
Intent openPlayer = new Intent(TracksActivity.this, MusicPlayerActivity.class);
openPlayer.putExtra("song", position);
startActivity(openPlayer);
});
}
}
activity我要取回传过来的对象:
package com.example.musicalstructureapp;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
public class MusicPlayerActivity extends TracksActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
Intent passedIntent = getIntent();
Songs song = (Songs) passedIntent.getParcelableExtra("song");
TextView currentArtist = findViewById(R.id.currentArtistName_text_view);
TextView currentTrack = findViewById(R.id.currentTrackName_text_view);
TextView currentAlbum = findViewById(R.id.currentAlbumName_text_view);
ImageView currentCover = findViewById(R.id.currentAlbumCover_image_view);
currentArtist.setText(song.getArtist());
currentTrack.setText(song.getTrack());
currentAlbum.setText(song.getAlbum());
currentCover.setImageResource(song.getCover());
}
}
将openPlayer.putExtra("song", position);
更改为openPlayer.putExtra("song", songs.get(position));
现在您正在将 int(position 是 int)值发送到您的 MusicPlayerActivity
并将其投射到 Songs。因此在 currentArtist.setText(song.getArtist());
你得到 nullpointerexception
.