簡體   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