问题描述
我一直在尝试将 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)
这个输出是什么意思?
尝试在空对象引用上调用虚拟方法“java.lang.String com.example.musicalstructureapp.songs.getArtist()”
我已经像这样实现了 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();
}
}
My TracksActivity 包含对象列表并使用 onItemClickListener 打开新活动并传递对象:
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.track_two),getString(R.string.track_three),getString(R.string.track_four),getString(R.string.track_five),getString(R.string.track_six),getString(R.string.track_seven),getString(R.string.track_eight),getString(R.string.track_nine),getString(R.string.track_ten),getString(R.string.track_eleven),getString(R.string.track_twelve),getString(R.string.track_thirteen),getString(R.string.track_fourteen),getString(R.string.track_fifteen),getString(R.string.track_sixteen),getString(R.string.track_seventeen),getString(R.string.track_eighteen),getString(R.string.track_nineteen),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);
});
}
}
我要检索传递对象的活动:
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));
现在,您正在向 MusicPlayerActivity
发送 int(位置为 int)值并将其转换为 Songs。因此,在 currentArtist.setText(song.getArtist());
,您将获得 nullpointerexception
。