传递对象在活动意图中返回 null

Posted

技术标签:

【中文标题】传递对象在活动意图中返回 null【英文标题】:Passing Object returns null in acitivity intent 【发布时间】:2017-10-15 04:33:13 【问题描述】:

我正在尝试通过意图将数据从活动发送到其他活动。发送 Stringinteger 工作得很好。但是当我以相同的意图添加 Parecelable 对象时,它总是为 StringsIntegers 返回 null对象。下面是我将数据设置为意图的代码。

Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("SomeText", "sometext");
intent.putExtra("itemId", itemId);
intent.putExtra("someuser",user);

startActivity(intent);

在其他活动中,我得到的值如下:

String som = getIntent().getStringExtra("SomeText");
int itemird = getIntent().getIntExtra("itemId", 0);
User user = getIntent().getParcelableExtra("someuser");

我也尝试了不同的其他解决方案,如this 和 this 和 this

这里有人可以建议我我的错误是什么或更好的解决方案吗?

所以这是我的 Parcelable 类

public class User implements Parcelable
    private int mData;
    private String username;
    private String imagePath;
    private String userId;

    public String getUserId() 
        return userId;
    

    public void setUserId(String userId) 
        this.userId = userId;
    

    public String getUsername() 
        return username;
    

    public void setUsername(String username) 
        this.username = username;
    

    public void setImagePath(String imagePath) 
        this.imagePath = imagePath;
    

    public String getImagePath() 
        return imagePath;

    

    public User() 

    

    public User(String username, String userId) 
        this.username = username;
        this.userId = userId;
    
    public User(String username) 
        this.username = username;
    
    @Override
    public int describeContents() 
        return 0;
    

    @Override
    public void writeToParcel(Parcel dest, int flags) 

    

    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() 
        public User createFromParcel(Parcel in) 
            return new User(in);
        

        public User[] newArray(int size) 
            return new User[size];
        
    ;

    private User(Parcel in) 
        mData = in.readInt();
    


【问题讨论】:

您可以使您的自定义 Java 对象实现 Serializable 并使用 putExtra。如果它不起作用,请粘贴错误日志。 这可能是您的 User 类中实现 parcelable 接口方法的问题。你能把这些方法贴在这里吗? 你必须坚持writeToParcel 中的所有属性并在构造函数User(Parcel in) 中读取所有属性,请参阅此链接以获得更好的我的意思***.com/questions/21250339/… 【参考方案1】:

仔细阅读thisJeremy Logan的答案。你应该:

1) 为您的User 类实现Parcelable

2) 你的User 类的类转换,如User user = (User) getIntent().getParcelableExtra("someuser")intent.putExtra("someuser", (Parcelable)user)

【讨论】:

我的用户对象是一个 Parcelable 对象。 所以检查public static final Parcelable.Creator方法。【参考方案2】:

像这样的结构传递对象

Bundle b = new Bundle();
b.putParcelable("someuser",user);
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("SomeText", "sometext");
intent.putExtra("itemId", itemId);
intent.putExtra(b);
startActivity(intent);

然后收到这样的

Bundle b = getIntent().getExtras();
if(b != null) 
User user = b.getParcelable("someuser");   

【讨论】:

【参考方案3】:

创建一个 Parcelable 类

    public class User implements Parcelable

        String name;


        @Override
        public int describeContents() 
            // TODO Auto-generated method stub
            return 0;
        

        /**
        * Storing the User data to Parcel object
        **/
        @Override
        public void writeToParcel(Parcel dest, int flags) 
            dest.writeString(name);


        

        /**
        * A constructor that initializes the User object
        **/
        public User(String uName)
            this.name = uName;

        

        /**
        * Retrieving User data from Parcel object
        * This constructor is invoked by the method createFromParcel(Parcel source) of
        * the object CREATOR
        **/
        private Student(Parcel in)
            this.mSName = in.readString();

        

        public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() 

            @Override
            public User createFromParcel(Parcel source) 
                return new User(source);
            

            @Override
            public User[] newArray(int size) 
                return new User[size];
            
        ;
    

public class MainActivity extends Activity 

    @Override
        protected void onCreate(Bundle savedInstanceState) 
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

       mBtnOk.setOnClickListener(new OnClickListener() 

                @Override
                public void onClick(View v) 

                    // Creating an instance of Student class with user input data
                    User userObj= new User ("Name");

                    // Creating an intent to open the activity 
                    Intent intent = new Intent(MainActivity.this, NextActivity.class);

                    // Passing data as a parecelable object to 
                    intent.putExtra("user",userObj);

                    // Opening the activity
                    startActivity(intent);
                
            );



    

    





    public class NextActivity extends Activity 

    @Override
        protected void onCreate(Bundle savedInstanceState) 
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_next);

     // Fetching data from a parcelable object passed from MainActivity
            User user= getIntent().getParcelableExtra("user");



    

    

【讨论】:

@SairaNawaz 在您的 writeToParcel() 方法中检查您的课程 dest.writeString(name);在您的代码中添加此行作为名称和 ID。!【参考方案4】:

尝试使用此解决方案更改您的 User 类,如下所示:

public class User implements Parcelable 
private int mData;
private String username;
private String imagePath;
private String userId;

public String getUserId() 
    return userId;


public void setUserId(String userId) 
    this.userId = userId;


public String getUsername() 
    return username;


public void setUsername(String username) 
    this.username = username;


public void setImagePath(String imagePath) 
    this.imagePath = imagePath;


public String getImagePath() 
    return imagePath;



public User() 


public User(String username, String userId) 
    this.username = username;
    this.userId = userId;

public User(String username) 
    this.username = username;

@Override
public int describeContents() 
    return 0;


@Override
public void writeToParcel(Parcel dest, int flags) 

    dest.writeInt(mData);
    dest.writeString(username);
    dest.writeString(imagePath);
    dest.writeString(userId);


private void readFromParcel(Parcel in ) 

    mData     = in .readInt();
    username  = in .readString();
    imagePath = in .readString();
    userId    = in .readString();


public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() 
    public User createFromParcel(Parcel in) 
        return new User(in);
    

    public User[] newArray(int size) 
        return new User[size];
    
;

    private User(Parcel in) 
        readFromParcel( in );
    


【讨论】:

【参考方案5】:

我认为您没有正确实现您的用户模型类。 你可以试试这个

public class User implements Parcelable 

private int mData;
private String username;
private String imagePath;
private String userId;

public User(String username, String userId) 
    this.username = username;
    this.userId = userId;

public User(String username) 
    this.username = username;

public User()  // empty constructor

public String getUserId() 
    return userId;


public void setUserId(String userId) 
    this.userId = userId;


public String getUsername() 
    return username;


public void setUsername(String username) 
    this.username = username;


public void setImagePath(String imagePath) 
    this.imagePath = imagePath;


public String getImagePath() 
    return imagePath;



@Override
public int describeContents() 
    return 0;

@Override
public void writeToParcel(Parcel dest, int flags) 

    dest.writeInt(mData);
    dest.writeString(username);
    dest.writeString(imagePath);
    dest.writeString(userId);


private User(Parcel in) 
    mData     = in.readInt();
    username  = in.readString();
    imagePath = in.readString();
    userId    = in.readString();.


public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() 
    public User createFromParcel(Parcel in) 
        return new User(in);
    

    public User[] newArray(int size) 
        return new User[size];
    
;

然后在您的 Splash 活动中,您可以执行此操作。我假设您已经创建了一个要发送到 MainActivity 的用户对象

Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("someuser",user); // using the (String name, Parcelable value) overload! 
intent.putExtra("SomeText", "sometext");
intent.putExtra("itemId", itemId);
intent.putExtra(bundle);

startActivity(intent);

然后你可以像这样在 MainActivity 中接收它

User user = (User) getIntent().getParcelableExtra("someuser");

【讨论】:

【参考方案6】:

如果 serializable 易于使用且易于理解和实现,为什么还要使用 parcelable

在你的类中实现可序列化

public class Place implements Serializable 
        private int id;
        private String name;

        public void setId(int id) 
            this.id = id;
        

        public int getId() 
            return id;
        

        public String getName() 
            return name;
        

        public void setName(String name) 
            this.name = name;
        
     

那么就可以intent传递这个对象了

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity();

在第二个活动中你可以得到这样的数据

 Place place= (Place) getIntent().getSerializableExtra("PLACE");

parcelable 用于需要发送大数据的时候,否则你可以使用 serializable

如果不行请告诉我

【讨论】:

内部类也需要序列化 把你的课程发给我 它不起作用,因为显然这是预期的行为......code.google.com/p/android/issues/detail?id=216581【参考方案7】:

我尝试了所有解决方案,但没有人提到这个解决方案,writeToParcel() 是有问题的。包裹应该按照相同的顺序写入和读取。

【讨论】:

以上是关于传递对象在活动意图中返回 null的主要内容,如果未能解决你的问题,请参考以下文章

在 JNI 中传递对象总是返回 NULL

活动结果相机意图在三星 s4 中返回 null

意图过滤器:intent.getData() 返回 null

试图从谷歌地图获取纬度是通过 Android 中的意图返回 null

当通过意图从相机应用程序返回时,Android 活动被破坏

方法 getParcelableExtra() 在创建意图时返回 null