繁体   English   中英

Android Parcelable对象在活动之间无法正常传递

[英]Android Parcelable object not passing properly between activities

过去两天这一直令我头疼。 奇怪的是,在将一个对象从activity传递给fragment时,代码在一个项目中运行正常,但是我无法使该对象从activity转到activity,即使我似乎正在实现parcelable。

奇怪的是,我没有在另一端获得一个null对象,但该对象在其中有空值。

我已经创建了一个新项目来测试它。 这是到目前为止的代码:

MainActivity.java:

    package com.example.parcleableexample;

    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Intent;
    import android.view.Menu;
    import android.view.View;
    import android.widget.TextView;

    public class MainActivity extends Activity {
        Site mySite = new Site();


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mySite.setSiteName("hi");
            TextView myText = (TextView) findViewById(R.id.txtSiteName);
            myText.setText(mySite.getSiteName());
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }


        public void doThing (View v) {
            Intent mIntent = new Intent(this,AnotherActivity.class);
            mIntent.putExtra("site", mySite);
            startActivity(mIntent);
        }
    }

AnotherActivity.java:

package com.example.parcleableexample;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.TextView;

public class AnotherActivity extends Activity {

    Site mySite = new Site();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mySite = getIntent().getParcelableExtra("site");
            TextView myText = (TextView) findViewById(R.id.txtSiteName);
            myText.setText(mySite.getSiteName());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

Site.Java:

package com.example.parcleableexample;

import android.os.Parcel;
import android.os.Parcelable;

public class Site implements Parcelable {

    private String siteName;

    Site() {
        // Empty Constructor
    }

    public String getSiteName() {
        return siteName;
    }

    public void setSiteName(String siteName) {
        this.siteName = siteName;
    }

    // Parcleable Functions:
    private int mData;
    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

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

        public Site[] newArray(int size) {
            return new Site[size];
        }
    };

    private Site(Parcel in) {
        mData = in.readInt();
    }
}

activity_main.xml中:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/txtSiteName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/txtSiteName"
        android:layout_below="@+id/txtSiteName"
        android:layout_marginLeft="42dp"
        android:layout_marginTop="25dp"
        android:onClick="doThing"
        android:text="Button" />

</RelativeLayout>

我期望的是,“hi”值出现在两次,一次是在我启动应用程序时,再次是当我单击按钮并且新活动创建时。

但是,它仅在第一次正确显示时,第二次getSiteName仅返回null。

我还直接从工作应用程序复制并粘贴了Site对象,结果相同,但它可以在工作应用程序中按预期工作; Site对象被正确复制。

工作应用程序运行此代码:

Bundle arguments = new Bundle();
arguments.putParcelable("site", SearchResults.get(position));
ViewSiteFragment myFragment = new ViewSiteFragment();
myFragment.setArguments(arguments);
FragmentTransaction myTransaction = getFragmentManager().beginTransaction();
myTransaction.replace(R.id.MainFragmentContainer, myFragment);
myTransaction.addToBackStack(null);
myTransaction.commit();

并在这里拾取另一端的对象:

Site mSite = getArguments().getParcelable("site");

我知道我做错了什么......只是不知道我错过了什么!

问题出在Parcelable的实现上。 siteName永远不会写入parcel,而是编写mData,它从不在任何地方使用。 如果需要,可以保留mData,并为siteName添加ADD写入,请参阅代码:

public void writeToParcel(Parcel out, int flags) {
    out.writeInt(mData);

    //we want to keep siteName in our parcel, so let's write it to the Parcel obj
    out.writeString(siteName);
}

稍后,添加此代码以从包裹中读取:

private Site(Parcel in) {
    mData = in.readInt();

    //let's read from in Parcel an set our siteName
    siteName = in.readString();
}

像bundle对象一样接收它:

在activity2中,在onCreate()中,您可以通过检索bundle(包含调用活动发送的所有消息)来获取String消息/对象并调用:

Bundle bundle = getIntent().getExtras();
mySite = bundle.getParcelableExtra("site");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM